diff --git a/KRecordContainerFlash/.actionScriptProperties b/KRecordContainerFlash/.actionScriptProperties new file mode 100644 index 0000000..c63bdf0 --- /dev/null +++ b/KRecordContainerFlash/.actionScriptProperties @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/KRecordContainerFlash/.project b/KRecordContainerFlash/.project new file mode 100644 index 0000000..4f73e2e --- /dev/null +++ b/KRecordContainerFlash/.project @@ -0,0 +1,24 @@ + + + KRecordContainerFlash + + + + + + com.adobe.flexbuilder.project.flexbuilder + + + + + + com.adobe.flexbuilder.project.actionscriptnature + + + + bin-debug + 2 + C:/xampp/htdocs/KRecordContainerFlash + + + diff --git a/KRecordContainerFlash/.settings/com.adobe.flexbuilder.project.prefs b/KRecordContainerFlash/.settings/com.adobe.flexbuilder.project.prefs new file mode 100644 index 0000000..4a85376 --- /dev/null +++ b/KRecordContainerFlash/.settings/com.adobe.flexbuilder.project.prefs @@ -0,0 +1,3 @@ +#Mon Aug 02 10:07:31 IDT 2010 +eclipse.preferences.version=1 +upgradeSDK/fb4= diff --git a/KRecordContainerFlash/html-template/AC_OETags.js b/KRecordContainerFlash/html-template/AC_OETags.js new file mode 100644 index 0000000..9fec640 --- /dev/null +++ b/KRecordContainerFlash/html-template/AC_OETags.js @@ -0,0 +1,278 @@ +// Flash Player Version Detection - Rev 1.6 +// Detect Client Browser type +// Copyright(c) 2005-2006 Adobe Macromedia Software, LLC. All rights reserved. +var isIE = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false; +var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false; +var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false; + +function ControlVersion() +{ + var version; + var axo; + var e; + + // NOTE : new ActiveXObject(strFoo) throws an exception if strFoo isn't in the registry + + try { + // version will be set for 7.X or greater players + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7"); + version = axo.GetVariable("$version"); + } catch (e) { + } + + if (!version) + { + try { + // version will be set for 6.X players only + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"); + + // installed player is some revision of 6.0 + // GetVariable("$version") crashes for versions 6.0.22 through 6.0.29, + // so we have to be careful. + + // default to the first public version + version = "WIN 6,0,21,0"; + + // throws if AllowScripAccess does not exist (introduced in 6.0r47) + axo.AllowScriptAccess = "always"; + + // safe to call for 6.0r47 or greater + version = axo.GetVariable("$version"); + + } catch (e) { + } + } + + if (!version) + { + try { + // version will be set for 4.X or 5.X player + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3"); + version = axo.GetVariable("$version"); + } catch (e) { + } + } + + if (!version) + { + try { + // version will be set for 3.X player + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3"); + version = "WIN 3,0,18,0"; + } catch (e) { + } + } + + if (!version) + { + try { + // version will be set for 2.X player + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); + version = "WIN 2,0,0,11"; + } catch (e) { + version = -1; + } + } + + return version; +} + +// JavaScript helper required to detect Flash Player PlugIn version information +function GetSwfVer(){ + // NS/Opera version >= 3 check for Flash plugin in plugin array + var flashVer = -1; + + if (navigator.plugins != null && navigator.plugins.length > 0) { + if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) { + var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : ""; + var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description; + var descArray = flashDescription.split(" "); + var tempArrayMajor = descArray[2].split("."); + var versionMajor = tempArrayMajor[0]; + var versionMinor = tempArrayMajor[1]; + var versionRevision = descArray[3]; + if (versionRevision == "") { + versionRevision = descArray[4]; + } + if (versionRevision[0] == "d") { + versionRevision = versionRevision.substring(1); + } else if (versionRevision[0] == "r") { + versionRevision = versionRevision.substring(1); + if (versionRevision.indexOf("d") > 0) { + versionRevision = versionRevision.substring(0, versionRevision.indexOf("d")); + } + } else if (versionRevision[0] == "b") { + versionRevision = versionRevision.substring(1); + } + var flashVer = versionMajor + "." + versionMinor + "." + versionRevision; + } + } + // MSN/WebTV 2.6 supports Flash 4 + else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4; + // WebTV 2.5 supports Flash 3 + else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3; + // older WebTV supports Flash 2 + else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2; + else if ( isIE && isWin && !isOpera ) { + flashVer = ControlVersion(); + } + return flashVer; +} + +// When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available +function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision) +{ + versionStr = GetSwfVer(); + if (versionStr == -1 ) { + return false; + } else if (versionStr != 0) { + if(isIE && isWin && !isOpera) { + // Given "WIN 2,0,0,11" + tempArray = versionStr.split(" "); // ["WIN", "2,0,0,11"] + tempString = tempArray[1]; // "2,0,0,11" + versionArray = tempString.split(","); // ['2', '0', '0', '11'] + } else { + versionArray = versionStr.split("."); + } + var versionMajor = versionArray[0]; + var versionMinor = versionArray[1]; + var versionRevision = versionArray[2]; + + // is the major.revision >= requested major.revision AND the minor version >= requested minor + if (versionMajor > parseFloat(reqMajorVer)) { + return true; + } else if (versionMajor == parseFloat(reqMajorVer)) { + if (versionMinor > parseFloat(reqMinorVer)) + return true; + else if (versionMinor == parseFloat(reqMinorVer)) { + if (versionRevision >= parseFloat(reqRevision)) + return true; + } + } + return false; + } +} + +function AC_AddExtension(src, ext) +{ + if (src.indexOf('?') != -1) + return src.replace(/\?/, ext+'?'); + else + return src + ext; +} + +function AC_Generateobj(objAttrs, params, embedAttrs) +{ + var str = ''; + if (isIE && isWin && !isOpera) + { + str += ' '; + str += ''; + } else { + str += ' 0 && typeof o[0].SetVariable != "undefined") { + return o[0]; + } + else if (e.length > 0 && typeof e[0].SetVariable != "undefined") { + return e[0]; + } + } + } + else { + var o = document.getElementsByTagName("object"); + var e = document.getElementsByTagName("embed"); + if (e.length > 0 && typeof e[0].SetVariable != "undefined") { + return e[0]; + } + else if (o.length > 0 && typeof o[0].SetVariable != "undefined") { + return o[0]; + } + else if (o.length > 1 && typeof o[1].SetVariable != "undefined") { + return o[1]; + } + } + return undefined; + } + + function getPlayers() { + var players = []; + if (players.length == 0) { + var tmp = document.getElementsByTagName('object'); + players = tmp; + } + + if (players.length == 0 || players[0].object == null) { + var tmp = document.getElementsByTagName('embed'); + players = tmp; + } + return players; + } + + function getIframeHash() { + var doc = getHistoryFrame().contentWindow.document; + var hash = String(doc.location.search); + if (hash.length == 1 && hash.charAt(0) == "?") { + hash = ""; + } + else if (hash.length >= 2 && hash.charAt(0) == "?") { + hash = hash.substring(1); + } + return hash; + } + + /* Get the current location hash excluding the '#' symbol. */ + function getHash() { + // It would be nice if we could use document.location.hash here, + // but it's faulty sometimes. + var idx = document.location.href.indexOf('#'); + return (idx >= 0) ? document.location.href.substr(idx+1) : ''; + } + + /* Get the current location hash excluding the '#' symbol. */ + function setHash(hash) { + // It would be nice if we could use document.location.hash here, + // but it's faulty sometimes. + if (hash == '') hash = '#' + document.location.hash = hash; + } + + function createState(baseUrl, newUrl, flexAppUrl) { + return { 'baseUrl': baseUrl, 'newUrl': newUrl, 'flexAppUrl': flexAppUrl, 'title': null }; + } + + /* Add a history entry to the browser. + * baseUrl: the portion of the location prior to the '#' + * newUrl: the entire new URL, including '#' and following fragment + * flexAppUrl: the portion of the location following the '#' only + */ + function addHistoryEntry(baseUrl, newUrl, flexAppUrl) { + + //delete all the history entries + forwardStack = []; + + if (browser.ie) { + //Check to see if we are being asked to do a navigate for the first + //history entry, and if so ignore, because it's coming from the creation + //of the history iframe + if (flexAppUrl == defaultHash && document.location.href == initialHref && window['_ie_firstload']) { + currentHref = initialHref; + return; + } + if ((!flexAppUrl || flexAppUrl == defaultHash) && window['_ie_firstload']) { + newUrl = baseUrl + '#' + defaultHash; + flexAppUrl = defaultHash; + } else { + // for IE, tell the history frame to go somewhere without a '#' + // in order to get this entry into the browser history. + getHistoryFrame().src = historyFrameSourcePrefix + flexAppUrl; + } + setHash(flexAppUrl); + } else { + + //ADR + if (backStack.length == 0 && initialState.flexAppUrl == flexAppUrl) { + initialState = createState(baseUrl, newUrl, flexAppUrl); + } else if(backStack.length > 0 && backStack[backStack.length - 1].flexAppUrl == flexAppUrl) { + backStack[backStack.length - 1] = createState(baseUrl, newUrl, flexAppUrl); + } + + if (browser.safari) { + // for Safari, submit a form whose action points to the desired URL + if (browser.version <= 419.3) { + var file = window.location.pathname.toString(); + file = file.substring(file.lastIndexOf("/")+1); + getFormElement().innerHTML = '
'; + //get the current elements and add them to the form + var qs = window.location.search.substring(1); + var qs_arr = qs.split("&"); + for (var i = 0; i < qs_arr.length; i++) { + var tmp = qs_arr[i].split("="); + var elem = document.createElement("input"); + elem.type = "hidden"; + elem.name = tmp[0]; + elem.value = tmp[1]; + document.forms.historyForm.appendChild(elem); + } + document.forms.historyForm.submit(); + } else { + top.location.hash = flexAppUrl; + } + // We also have to maintain the history by hand for Safari + historyHash[history.length] = flexAppUrl; + _storeStates(); + } else { + // Otherwise, write an anchor into the page and tell the browser to go there + addAnchor(flexAppUrl); + setHash(flexAppUrl); + } + } + backStack.push(createState(baseUrl, newUrl, flexAppUrl)); + } + + function _storeStates() { + if (browser.safari) { + getRememberElement().value = historyHash.join(","); + } + } + + function handleBackButton() { + //The "current" page is always at the top of the history stack. + var current = backStack.pop(); + if (!current) { return; } + var last = backStack[backStack.length - 1]; + if (!last && backStack.length == 0){ + last = initialState; + } + forwardStack.push(current); + } + + function handleForwardButton() { + //summary: private method. Do not call this directly. + + var last = forwardStack.pop(); + if (!last) { return; } + backStack.push(last); + } + + function handleArbitraryUrl() { + //delete all the history entries + forwardStack = []; + } + + /* Called periodically to poll to see if we need to detect navigation that has occurred */ + function checkForUrlChange() { + + if (browser.ie) { + if (currentHref != document.location.href && currentHref + '#' != document.location.href) { + //This occurs when the user has navigated to a specific URL + //within the app, and didn't use browser back/forward + //IE seems to have a bug where it stops updating the URL it + //shows the end-user at this point, but programatically it + //appears to be correct. Do a full app reload to get around + //this issue. + if (browser.version < 7) { + currentHref = document.location.href; + document.location.reload(); + } else { + if (getHash() != getIframeHash()) { + // this.iframe.src = this.blankURL + hash; + var sourceToSet = historyFrameSourcePrefix + getHash(); + getHistoryFrame().src = sourceToSet; + } + } + } + } + + if (browser.safari) { + // For Safari, we have to check to see if history.length changed. + if (currentHistoryLength >= 0 && history.length != currentHistoryLength) { + //alert("did change: " + history.length + ", " + historyHash.length + "|" + historyHash[history.length] + "|>" + historyHash.join("|")); + // If it did change, then we have to look the old state up + // in our hand-maintained array since document.location.hash + // won't have changed, then call back into BrowserManager. + currentHistoryLength = history.length; + var flexAppUrl = historyHash[currentHistoryLength]; + if (flexAppUrl == '') { + //flexAppUrl = defaultHash; + } + //ADR: to fix multiple + if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) { + var pl = getPlayers(); + for (var i = 0; i < pl.length; i++) { + pl[i].browserURLChange(flexAppUrl); + } + } else { + getPlayer().browserURLChange(flexAppUrl); + } + _storeStates(); + } + } + if (browser.firefox) { + if (currentHref != document.location.href) { + var bsl = backStack.length; + + var urlActions = { + back: false, + forward: false, + set: false + } + + if ((window.location.hash == initialHash || window.location.href == initialHref) && (bsl == 1)) { + urlActions.back = true; + // FIXME: could this ever be a forward button? + // we can't clear it because we still need to check for forwards. Ugg. + // clearInterval(this.locationTimer); + handleBackButton(); + } + + // first check to see if we could have gone forward. We always halt on + // a no-hash item. + if (forwardStack.length > 0) { + if (forwardStack[forwardStack.length-1].flexAppUrl == getHash()) { + urlActions.forward = true; + handleForwardButton(); + } + } + + // ok, that didn't work, try someplace back in the history stack + if ((bsl >= 2) && (backStack[bsl - 2])) { + if (backStack[bsl - 2].flexAppUrl == getHash()) { + urlActions.back = true; + handleBackButton(); + } + } + + if (!urlActions.back && !urlActions.forward) { + var foundInStacks = { + back: -1, + forward: -1 + } + + for (var i = 0; i < backStack.length; i++) { + if (backStack[i].flexAppUrl == getHash() && i != (bsl - 2)) { + arbitraryUrl = true; + foundInStacks.back = i; + } + } + for (var i = 0; i < forwardStack.length; i++) { + if (forwardStack[i].flexAppUrl == getHash() && i != (bsl - 2)) { + arbitraryUrl = true; + foundInStacks.forward = i; + } + } + handleArbitraryUrl(); + } + + // Firefox changed; do a callback into BrowserManager to tell it. + currentHref = document.location.href; + var flexAppUrl = getHash(); + if (flexAppUrl == '') { + //flexAppUrl = defaultHash; + } + //ADR: to fix multiple + if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) { + var pl = getPlayers(); + for (var i = 0; i < pl.length; i++) { + pl[i].browserURLChange(flexAppUrl); + } + } else { + getPlayer().browserURLChange(flexAppUrl); + } + } + } + //setTimeout(checkForUrlChange, 50); + } + + /* Write an anchor into the page to legitimize it as a URL for Firefox et al. */ + function addAnchor(flexAppUrl) + { + if (document.getElementsByName(flexAppUrl).length == 0) { + getAnchorElement().innerHTML += "" + flexAppUrl + ""; + } + } + + var _initialize = function () { + if (browser.ie) + { + var scripts = document.getElementsByTagName('script'); + for (var i = 0, s; s = scripts[i]; i++) { + if (s.src.indexOf("history.js") > -1) { + var iframe_location = (new String(s.src)).replace("history.js", "historyFrame.html"); + } + } + historyFrameSourcePrefix = iframe_location + "?"; + var src = historyFrameSourcePrefix; + + var iframe = document.createElement("iframe"); + iframe.id = 'ie_historyFrame'; + iframe.name = 'ie_historyFrame'; + //iframe.src = historyFrameSourcePrefix; + try { + document.body.appendChild(iframe); + } catch(e) { + setTimeout(function() { + document.body.appendChild(iframe); + }, 0); + } + } + + if (browser.safari) + { + var rememberDiv = document.createElement("div"); + rememberDiv.id = 'safari_rememberDiv'; + document.body.appendChild(rememberDiv); + rememberDiv.innerHTML = ''; + + var formDiv = document.createElement("div"); + formDiv.id = 'safari_formDiv'; + document.body.appendChild(formDiv); + + var reloader_content = document.createElement('div'); + reloader_content.id = 'safarireloader'; + var scripts = document.getElementsByTagName('script'); + for (var i = 0, s; s = scripts[i]; i++) { + if (s.src.indexOf("history.js") > -1) { + html = (new String(s.src)).replace(".js", ".html"); + } + } + reloader_content.innerHTML = ''; + document.body.appendChild(reloader_content); + reloader_content.style.position = 'absolute'; + reloader_content.style.left = reloader_content.style.top = '-9999px'; + iframe = reloader_content.getElementsByTagName('iframe')[0]; + + if (document.getElementById("safari_remember_field").value != "" ) { + historyHash = document.getElementById("safari_remember_field").value.split(","); + } + + } + + if (browser.firefox) + { + var anchorDiv = document.createElement("div"); + anchorDiv.id = 'firefox_anchorDiv'; + document.body.appendChild(anchorDiv); + } + + //setTimeout(checkForUrlChange, 50); + } + + return { + historyHash: historyHash, + backStack: function() { return backStack; }, + forwardStack: function() { return forwardStack }, + getPlayer: getPlayer, + initialize: function(src) { + _initialize(src); + }, + setURL: function(url) { + document.location.href = url; + }, + getURL: function() { + return document.location.href; + }, + getTitle: function() { + return document.title; + }, + setTitle: function(title) { + try { + backStack[backStack.length - 1].title = title; + } catch(e) { } + //if on safari, set the title to be the empty string. + if (browser.safari) { + if (title == "") { + try { + var tmp = window.location.href.toString(); + title = tmp.substring((tmp.lastIndexOf("/")+1), tmp.lastIndexOf("#")); + } catch(e) { + title = ""; + } + } + } + document.title = title; + }, + setDefaultURL: function(def) + { + defaultHash = def; + def = getHash(); + //trailing ? is important else an extra frame gets added to the history + //when navigating back to the first page. Alternatively could check + //in history frame navigation to compare # and ?. + if (browser.ie) + { + window['_ie_firstload'] = true; + var sourceToSet = historyFrameSourcePrefix + def; + var func = function() { + getHistoryFrame().src = sourceToSet; + window.location.replace("#" + def); + setInterval(checkForUrlChange, 50); + } + try { + func(); + } catch(e) { + window.setTimeout(function() { func(); }, 0); + } + } + + if (browser.safari) + { + currentHistoryLength = history.length; + if (historyHash.length == 0) { + historyHash[currentHistoryLength] = def; + var newloc = "#" + def; + window.location.replace(newloc); + } else { + //alert(historyHash[historyHash.length-1]); + } + //setHash(def); + setInterval(checkForUrlChange, 50); + } + + + if (browser.firefox || browser.opera) + { + var reg = new RegExp("#" + def + "$"); + if (window.location.toString().match(reg)) { + } else { + var newloc ="#" + def; + window.location.replace(newloc); + } + setInterval(checkForUrlChange, 50); + //setHash(def); + } + + }, + + /* Set the current browser URL; called from inside BrowserManager to propagate + * the application state out to the container. + */ + setBrowserURL: function(flexAppUrl, objectId) { + if (browser.ie && typeof objectId != "undefined") { + currentObjectId = objectId; + } + //fromIframe = fromIframe || false; + //fromFlex = fromFlex || false; + //alert("setBrowserURL: " + flexAppUrl); + //flexAppUrl = (flexAppUrl == "") ? defaultHash : flexAppUrl ; + + var pos = document.location.href.indexOf('#'); + var baseUrl = pos != -1 ? document.location.href.substr(0, pos) : document.location.href; + var newUrl = baseUrl + '#' + flexAppUrl; + + if (document.location.href != newUrl && document.location.href + '#' != newUrl) { + currentHref = newUrl; + addHistoryEntry(baseUrl, newUrl, flexAppUrl); + currentHistoryLength = history.length; + } + + return false; + }, + + browserURLChange: function(flexAppUrl) { + var objectId = null; + if (browser.ie && currentObjectId != null) { + objectId = currentObjectId; + } + pendingURL = ''; + + if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) { + var pl = getPlayers(); + for (var i = 0; i < pl.length; i++) { + try { + pl[i].browserURLChange(flexAppUrl); + } catch(e) { } + } + } else { + try { + getPlayer(objectId).browserURLChange(flexAppUrl); + } catch(e) { } + } + + currentObjectId = null; + } + + } + +})(); + +// Initialization + +// Automated unit testing and other diagnostics + +function setURL(url) +{ + document.location.href = url; +} + +function backButton() +{ + history.back(); +} + +function forwardButton() +{ + history.forward(); +} + +function goForwardOrBackInHistory(step) +{ + history.go(step); +} + +//BrowserHistoryUtils.addEvent(window, "load", function() { BrowserHistory.initialize(); }); +(function(i) { + var u =navigator.userAgent;var e=/*@cc_on!@*/false; + var st = setTimeout; + if(/webkit/i.test(u)){ + st(function(){ + var dr=document.readyState; + if(dr=="loaded"||dr=="complete"){i()} + else{st(arguments.callee,10);}},10); + } else if((/mozilla/i.test(u)&&!/(compati)/.test(u)) || (/opera/i.test(u))){ + document.addEventListener("DOMContentLoaded",i,false); + } else if(e){ + (function(){ + var t=document.createElement('doc:rdy'); + try{t.doScroll('left'); + i();t=null; + }catch(e){st(arguments.callee,0);}})(); + } else{ + window.onload=i; + } +})( function() {BrowserHistory.initialize();} ); diff --git a/KRecordContainerFlash/html-template/history/historyFrame.html b/KRecordContainerFlash/html-template/history/historyFrame.html new file mode 100644 index 0000000..aebb8d8 --- /dev/null +++ b/KRecordContainerFlash/html-template/history/historyFrame.html @@ -0,0 +1,29 @@ + + + + + + + + Hidden frame for Browser History support. + + diff --git a/KRecordContainerFlash/html-template/index.template.html b/KRecordContainerFlash/html-template/index.template.html new file mode 100644 index 0000000..0c621fd --- /dev/null +++ b/KRecordContainerFlash/html-template/index.template.html @@ -0,0 +1,139 @@ + + + + + + + + + + + + +${title} + + + + + + + + + + + + + + + diff --git a/KRecordContainerFlash/html-template/locale.xml b/KRecordContainerFlash/html-template/locale.xml new file mode 100644 index 0000000..94bc76a --- /dev/null +++ b/KRecordContainerFlash/html-template/locale.xml @@ -0,0 +1,43 @@ + + + + Button.StopRecord + Click anywhere to stop recording + + + + Button.StartRecord + Click anywhere to start recording + + + + Button.Save + Save + + + + Button.Yes + Yes + + + + Button.No + No + + + + Dialog.Overwrite + Record again without saving? + + + + Dialog.Connecting + Connecting... + + + + Dialog.ConnectionError + Connection error. Please try again later + + + \ No newline at end of file diff --git a/KRecordContainerFlash/html-template/playerProductInstall.swf b/KRecordContainerFlash/html-template/playerProductInstall.swf new file mode 100644 index 0000000..bdc3437 Binary files /dev/null and b/KRecordContainerFlash/html-template/playerProductInstall.swf differ diff --git a/KRecordContainerFlash/html-template/skin.swf b/KRecordContainerFlash/html-template/skin.swf new file mode 100644 index 0000000..9e2724a Binary files /dev/null and b/KRecordContainerFlash/html-template/skin.swf differ diff --git a/KRecordContainerFlash/src/KRecordContainerFlash.as b/KRecordContainerFlash/src/KRecordContainerFlash.as new file mode 100644 index 0000000..f81aaf0 --- /dev/null +++ b/KRecordContainerFlash/src/KRecordContainerFlash.as @@ -0,0 +1,81 @@ +package { + import flash.display.Loader; + import flash.display.Sprite; + import flash.display.StageAlign; + import flash.display.StageScaleMode; + import flash.events.Event; + import flash.events.EventDispatcher; + import flash.events.MouseEvent; + import flash.net.URLRequest; + import flash.system.ApplicationDomain; + import flash.system.LoaderContext; + + public class KRecordContainerFlash extends Sprite + { + private var _kRecorderLoader:Loader = new Loader(); + + private var button:Sprite = new Sprite(); + + public function KRecordContainerFlash() + { + stage.scaleMode = StageScaleMode.NO_SCALE; + stage.align = StageAlign.TOP_LEFT; + addEventListener(Event.ADDED_TO_STAGE, startApplication); + } + + private function startApplication (event:Event):void + { + removeEventListener(Event.ADDED_TO_STAGE, startApplication); + button.graphics.beginFill(0xff, 1); + button.graphics.drawCircle(0, 0, 50); + button.graphics.endFill(); + button.buttonMode = true; + button.useHandCursor = true; + button.addEventListener(MouseEvent.CLICK, buttonClickHandler); + addChild(button); + + _kRecorderLoader.x = 100; + _kRecorderLoader.y = 100; + _kRecorderLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, finishedLoading); + _kRecorderLoader.load(new URLRequest("KRecord.swf"), new LoaderContext(true, ApplicationDomain.currentDomain)); + } + + private function finishedLoading(event:Event):void + { + //wait for the krecord view to load - + _kRecorderLoader.addEventListener("viewReady", krecordReady); + //when loading inside another flash application, to pass initialization parameters to the krecord application, use the parameters object + //if loaded through HTML directly, the initialization will be directed through the embed object flashVars. + _kRecorderLoader.content['parameters'] = {themeUrl:"skin.swf", + localeUrl:"locale.xml", + autoPreview:"1", + pid:"1", + subpid:"100", + ks:"some generated ks here..." }; + //_kRecorderLoader.content['parameters'] = root.loaderInfo.parameters; + addChild(_kRecorderLoader); + } + + private function krecordReady (event:Event):void + { + //when krecord view is ready, it can be resized + _kRecorderLoader.width = 100 + Math.random() * 200; + _kRecorderLoader.height = _kRecorderLoader.width * 0.75; + + //when krecord application is ready, it can be accessed for APIs + //to access krecord application, use the application property: + trace("Available microphones: " + _kRecorderLoader.content["application"].getMicrophones()); + (_kRecorderLoader.content["application"] as EventDispatcher).addEventListener("addEntryFault", addEntryFaultHandler); + } + + private function addEntryFaultHandler (event:Event):void { + trace ("can't save without KS..."); + } + + private function buttonClickHandler (event:MouseEvent):void + { + _kRecorderLoader.width = 100 + Math.random() * 600; + _kRecorderLoader.height = _kRecorderLoader.width * 0.75; + } + } +} diff --git a/KRecordContainerFlex/.actionScriptProperties b/KRecordContainerFlex/.actionScriptProperties new file mode 100644 index 0000000..10dc7fc --- /dev/null +++ b/KRecordContainerFlex/.actionScriptProperties @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/KRecordContainerFlex/.flexProperties b/KRecordContainerFlex/.flexProperties new file mode 100644 index 0000000..0435fc7 --- /dev/null +++ b/KRecordContainerFlex/.flexProperties @@ -0,0 +1,2 @@ + + diff --git a/KRecordContainerFlex/.project b/KRecordContainerFlex/.project new file mode 100644 index 0000000..b6957c7 --- /dev/null +++ b/KRecordContainerFlex/.project @@ -0,0 +1,25 @@ + + + KRecordContainerFlex + + + + + + com.adobe.flexbuilder.project.flexbuilder + + + + + + com.adobe.flexbuilder.project.flexnature + com.adobe.flexbuilder.project.actionscriptnature + + + + bin-debug + 2 + C:/xampp/htdocs/KRecordContainer + + + diff --git a/KRecordContainerFlex/.settings/com.adobe.flexbuilder.project.prefs b/KRecordContainerFlex/.settings/com.adobe.flexbuilder.project.prefs new file mode 100644 index 0000000..b8cced3 --- /dev/null +++ b/KRecordContainerFlex/.settings/com.adobe.flexbuilder.project.prefs @@ -0,0 +1,3 @@ +#Mon Aug 02 10:08:22 IDT 2010 +eclipse.preferences.version=1 +upgradeSDK/fb4= diff --git a/KRecordContainerFlex/changelog.txt b/KRecordContainerFlex/changelog.txt new file mode 100644 index 0000000..5c8d12b --- /dev/null +++ b/KRecordContainerFlex/changelog.txt @@ -0,0 +1,2 @@ +Changed ApplicationLoader: stage to root +mouse leave \ No newline at end of file diff --git a/KRecordContainerFlex/html-template/AC_OETags.js b/KRecordContainerFlex/html-template/AC_OETags.js new file mode 100644 index 0000000..ba5d24a --- /dev/null +++ b/KRecordContainerFlex/html-template/AC_OETags.js @@ -0,0 +1,292 @@ +// Flash Player Version Detection - Rev 1.6 +// Detect Client Browser type +// Copyright(c) 2005-2006 Adobe Macromedia Software, LLC. All rights reserved. +var isIE = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false; +var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false; +var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false; + +function ControlVersion() +{ + var version; + var axo; + var e; + + // NOTE : new ActiveXObject(strFoo) throws an exception if strFoo isn't in the registry + + try { + // version will be set for 7.X or greater players + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7"); + version = axo.GetVariable("$version"); + } catch (e) { + } + + if (!version) + { + try { + // version will be set for 6.X players only + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"); + + // installed player is some revision of 6.0 + // GetVariable("$version") crashes for versions 6.0.22 through 6.0.29, + // so we have to be careful. + + // default to the first public version + version = "WIN 6,0,21,0"; + + // throws if AllowScripAccess does not exist (introduced in 6.0r47) + axo.AllowScriptAccess = "always"; + + // safe to call for 6.0r47 or greater + version = axo.GetVariable("$version"); + + } catch (e) { + } + } + + if (!version) + { + try { + // version will be set for 4.X or 5.X player + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3"); + version = axo.GetVariable("$version"); + } catch (e) { + } + } + + if (!version) + { + try { + // version will be set for 3.X player + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3"); + version = "WIN 3,0,18,0"; + } catch (e) { + } + } + + if (!version) + { + try { + // version will be set for 2.X player + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); + version = "WIN 2,0,0,11"; + } catch (e) { + version = -1; + } + } + + return version; +} + +// JavaScript helper required to detect Flash Player PlugIn version information +function GetSwfVer(){ + // NS/Opera version >= 3 check for Flash plugin in plugin array + var flashVer = -1; + + if (navigator.plugins != null && navigator.plugins.length > 0) { + if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) { + var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : ""; + var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description; + var descArray = flashDescription.split(" "); + var tempArrayMajor = descArray[2].split("."); + var versionMajor = tempArrayMajor[0]; + var versionMinor = tempArrayMajor[1]; + var versionRevision = descArray[3]; + if (versionRevision == "") { + versionRevision = descArray[4]; + } + if (versionRevision[0] == "d") { + versionRevision = versionRevision.substring(1); + } else if (versionRevision[0] == "r") { + versionRevision = versionRevision.substring(1); + if (versionRevision.indexOf("d") > 0) { + versionRevision = versionRevision.substring(0, versionRevision.indexOf("d")); + } + } else if (versionRevision[0] == "b") { + versionRevision = versionRevision.substring(1); + } + var flashVer = versionMajor + "." + versionMinor + "." + versionRevision; + } + } + // MSN/WebTV 2.6 supports Flash 4 + else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4; + // WebTV 2.5 supports Flash 3 + else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3; + // older WebTV supports Flash 2 + else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2; + else if ( isIE && isWin && !isOpera ) { + flashVer = ControlVersion(); + } + return flashVer; +} + +// When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available +function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision) +{ + versionStr = GetSwfVer(); + if (versionStr == -1 ) { + return false; + } else if (versionStr != 0) { + if(isIE && isWin && !isOpera) { + // Given "WIN 2,0,0,11" + tempArray = versionStr.split(" "); // ["WIN", "2,0,0,11"] + tempString = tempArray[1]; // "2,0,0,11" + versionArray = tempString.split(","); // ['2', '0', '0', '11'] + } else { + versionArray = versionStr.split("."); + } + var versionMajor = versionArray[0]; + var versionMinor = versionArray[1]; + var versionRevision = versionArray[2]; + + // is the major.revision >= requested major.revision AND the minor version >= requested minor + if (versionMajor > parseFloat(reqMajorVer)) { + return true; + } else if (versionMajor == parseFloat(reqMajorVer)) { + if (versionMinor > parseFloat(reqMinorVer)) + return true; + else if (versionMinor == parseFloat(reqMinorVer)) { + if (versionRevision >= parseFloat(reqRevision)) + return true; + } + } + return false; + } +} + +function AC_AddExtension(src, ext) +{ + var qIndex = src.indexOf('?'); + if ( qIndex != -1) + { + // Add the extention (if needed) before the query params + var path = src.substring(0, qIndex); + if (path.length >= ext.length && path.lastIndexOf(ext) == (path.length - ext.length)) + return src; + else + return src.replace(/\?/, ext+'?'); + } + else + { + // Add the extension (if needed) to the end of the URL + if (src.length >= ext.length && src.lastIndexOf(ext) == (src.length - ext.length)) + return src; // Already have extension + else + return src + ext; + } +} + +function AC_Generateobj(objAttrs, params, embedAttrs) +{ + var str = ''; + if (isIE && isWin && !isOpera) + { + str += ' '; + str += ''; + } else { + str += ' 0 && typeof o[0].SetVariable != "undefined") { + return o[0]; + } + else if (e.length > 0 && typeof e[0].SetVariable != "undefined") { + return e[0]; + } + } + } + else { + var o = document.getElementsByTagName("object"); + var e = document.getElementsByTagName("embed"); + if (e.length > 0 && typeof e[0].SetVariable != "undefined") { + return e[0]; + } + else if (o.length > 0 && typeof o[0].SetVariable != "undefined") { + return o[0]; + } + else if (o.length > 1 && typeof o[1].SetVariable != "undefined") { + return o[1]; + } + } + return undefined; + } + + function getPlayers() { + var players = []; + if (players.length == 0) { + var tmp = document.getElementsByTagName('object'); + players = tmp; + } + + if (players.length == 0 || players[0].object == null) { + var tmp = document.getElementsByTagName('embed'); + players = tmp; + } + return players; + } + + function getIframeHash() { + var doc = getHistoryFrame().contentWindow.document; + var hash = String(doc.location.search); + if (hash.length == 1 && hash.charAt(0) == "?") { + hash = ""; + } + else if (hash.length >= 2 && hash.charAt(0) == "?") { + hash = hash.substring(1); + } + return hash; + } + + /* Get the current location hash excluding the '#' symbol. */ + function getHash() { + // It would be nice if we could use document.location.hash here, + // but it's faulty sometimes. + var idx = document.location.href.indexOf('#'); + return (idx >= 0) ? document.location.href.substr(idx+1) : ''; + } + + /* Get the current location hash excluding the '#' symbol. */ + function setHash(hash) { + // It would be nice if we could use document.location.hash here, + // but it's faulty sometimes. + if (hash == '') hash = '#' + document.location.hash = hash; + } + + function createState(baseUrl, newUrl, flexAppUrl) { + return { 'baseUrl': baseUrl, 'newUrl': newUrl, 'flexAppUrl': flexAppUrl, 'title': null }; + } + + /* Add a history entry to the browser. + * baseUrl: the portion of the location prior to the '#' + * newUrl: the entire new URL, including '#' and following fragment + * flexAppUrl: the portion of the location following the '#' only + */ + function addHistoryEntry(baseUrl, newUrl, flexAppUrl) { + + //delete all the history entries + forwardStack = []; + + if (browser.ie) { + //Check to see if we are being asked to do a navigate for the first + //history entry, and if so ignore, because it's coming from the creation + //of the history iframe + if (flexAppUrl == defaultHash && document.location.href == initialHref && window['_ie_firstload']) { + currentHref = initialHref; + return; + } + if ((!flexAppUrl || flexAppUrl == defaultHash) && window['_ie_firstload']) { + newUrl = baseUrl + '#' + defaultHash; + flexAppUrl = defaultHash; + } else { + // for IE, tell the history frame to go somewhere without a '#' + // in order to get this entry into the browser history. + getHistoryFrame().src = historyFrameSourcePrefix + flexAppUrl; + } + setHash(flexAppUrl); + } else { + + //ADR + if (backStack.length == 0 && initialState.flexAppUrl == flexAppUrl) { + initialState = createState(baseUrl, newUrl, flexAppUrl); + } else if(backStack.length > 0 && backStack[backStack.length - 1].flexAppUrl == flexAppUrl) { + backStack[backStack.length - 1] = createState(baseUrl, newUrl, flexAppUrl); + } + + if (browser.safari) { + // for Safari, submit a form whose action points to the desired URL + if (browser.version <= 419.3) { + var file = window.location.pathname.toString(); + file = file.substring(file.lastIndexOf("/")+1); + getFormElement().innerHTML = '
'; + //get the current elements and add them to the form + var qs = window.location.search.substring(1); + var qs_arr = qs.split("&"); + for (var i = 0; i < qs_arr.length; i++) { + var tmp = qs_arr[i].split("="); + var elem = document.createElement("input"); + elem.type = "hidden"; + elem.name = tmp[0]; + elem.value = tmp[1]; + document.forms.historyForm.appendChild(elem); + } + document.forms.historyForm.submit(); + } else { + top.location.hash = flexAppUrl; + } + // We also have to maintain the history by hand for Safari + historyHash[history.length] = flexAppUrl; + _storeStates(); + } else { + // Otherwise, write an anchor into the page and tell the browser to go there + addAnchor(flexAppUrl); + setHash(flexAppUrl); + } + } + backStack.push(createState(baseUrl, newUrl, flexAppUrl)); + } + + function _storeStates() { + if (browser.safari) { + getRememberElement().value = historyHash.join(","); + } + } + + function handleBackButton() { + //The "current" page is always at the top of the history stack. + var current = backStack.pop(); + if (!current) { return; } + var last = backStack[backStack.length - 1]; + if (!last && backStack.length == 0){ + last = initialState; + } + forwardStack.push(current); + } + + function handleForwardButton() { + //summary: private method. Do not call this directly. + + var last = forwardStack.pop(); + if (!last) { return; } + backStack.push(last); + } + + function handleArbitraryUrl() { + //delete all the history entries + forwardStack = []; + } + + /* Called periodically to poll to see if we need to detect navigation that has occurred */ + function checkForUrlChange() { + + if (browser.ie) { + if (currentHref != document.location.href && currentHref + '#' != document.location.href) { + //This occurs when the user has navigated to a specific URL + //within the app, and didn't use browser back/forward + //IE seems to have a bug where it stops updating the URL it + //shows the end-user at this point, but programatically it + //appears to be correct. Do a full app reload to get around + //this issue. + if (browser.version < 7) { + currentHref = document.location.href; + document.location.reload(); + } else { + if (getHash() != getIframeHash()) { + // this.iframe.src = this.blankURL + hash; + var sourceToSet = historyFrameSourcePrefix + getHash(); + getHistoryFrame().src = sourceToSet; + } + } + } + } + + if (browser.safari) { + // For Safari, we have to check to see if history.length changed. + if (currentHistoryLength >= 0 && history.length != currentHistoryLength) { + //alert("did change: " + history.length + ", " + historyHash.length + "|" + historyHash[history.length] + "|>" + historyHash.join("|")); + // If it did change, then we have to look the old state up + // in our hand-maintained array since document.location.hash + // won't have changed, then call back into BrowserManager. + currentHistoryLength = history.length; + var flexAppUrl = historyHash[currentHistoryLength]; + if (flexAppUrl == '') { + //flexAppUrl = defaultHash; + } + //ADR: to fix multiple + if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) { + var pl = getPlayers(); + for (var i = 0; i < pl.length; i++) { + pl[i].browserURLChange(flexAppUrl); + } + } else { + getPlayer().browserURLChange(flexAppUrl); + } + _storeStates(); + } + } + if (browser.firefox) { + if (currentHref != document.location.href) { + var bsl = backStack.length; + + var urlActions = { + back: false, + forward: false, + set: false + } + + if ((window.location.hash == initialHash || window.location.href == initialHref) && (bsl == 1)) { + urlActions.back = true; + // FIXME: could this ever be a forward button? + // we can't clear it because we still need to check for forwards. Ugg. + // clearInterval(this.locationTimer); + handleBackButton(); + } + + // first check to see if we could have gone forward. We always halt on + // a no-hash item. + if (forwardStack.length > 0) { + if (forwardStack[forwardStack.length-1].flexAppUrl == getHash()) { + urlActions.forward = true; + handleForwardButton(); + } + } + + // ok, that didn't work, try someplace back in the history stack + if ((bsl >= 2) && (backStack[bsl - 2])) { + if (backStack[bsl - 2].flexAppUrl == getHash()) { + urlActions.back = true; + handleBackButton(); + } + } + + if (!urlActions.back && !urlActions.forward) { + var foundInStacks = { + back: -1, + forward: -1 + } + + for (var i = 0; i < backStack.length; i++) { + if (backStack[i].flexAppUrl == getHash() && i != (bsl - 2)) { + arbitraryUrl = true; + foundInStacks.back = i; + } + } + for (var i = 0; i < forwardStack.length; i++) { + if (forwardStack[i].flexAppUrl == getHash() && i != (bsl - 2)) { + arbitraryUrl = true; + foundInStacks.forward = i; + } + } + handleArbitraryUrl(); + } + + // Firefox changed; do a callback into BrowserManager to tell it. + currentHref = document.location.href; + var flexAppUrl = getHash(); + if (flexAppUrl == '') { + //flexAppUrl = defaultHash; + } + //ADR: to fix multiple + if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) { + var pl = getPlayers(); + for (var i = 0; i < pl.length; i++) { + pl[i].browserURLChange(flexAppUrl); + } + } else { + getPlayer().browserURLChange(flexAppUrl); + } + } + } + //setTimeout(checkForUrlChange, 50); + } + + /* Write an anchor into the page to legitimize it as a URL for Firefox et al. */ + function addAnchor(flexAppUrl) + { + if (document.getElementsByName(flexAppUrl).length == 0) { + getAnchorElement().innerHTML += "" + flexAppUrl + ""; + } + } + + var _initialize = function () { + if (browser.ie) + { + var scripts = document.getElementsByTagName('script'); + for (var i = 0, s; s = scripts[i]; i++) { + if (s.src.indexOf("history.js") > -1) { + var iframe_location = (new String(s.src)).replace("history.js", "historyFrame.html"); + } + } + historyFrameSourcePrefix = iframe_location + "?"; + var src = historyFrameSourcePrefix; + + var iframe = document.createElement("iframe"); + iframe.id = 'ie_historyFrame'; + iframe.name = 'ie_historyFrame'; + //iframe.src = historyFrameSourcePrefix; + try { + document.body.appendChild(iframe); + } catch(e) { + setTimeout(function() { + document.body.appendChild(iframe); + }, 0); + } + } + + if (browser.safari) + { + var rememberDiv = document.createElement("div"); + rememberDiv.id = 'safari_rememberDiv'; + document.body.appendChild(rememberDiv); + rememberDiv.innerHTML = ''; + + var formDiv = document.createElement("div"); + formDiv.id = 'safari_formDiv'; + document.body.appendChild(formDiv); + + var reloader_content = document.createElement('div'); + reloader_content.id = 'safarireloader'; + var scripts = document.getElementsByTagName('script'); + for (var i = 0, s; s = scripts[i]; i++) { + if (s.src.indexOf("history.js") > -1) { + html = (new String(s.src)).replace(".js", ".html"); + } + } + reloader_content.innerHTML = ''; + document.body.appendChild(reloader_content); + reloader_content.style.position = 'absolute'; + reloader_content.style.left = reloader_content.style.top = '-9999px'; + iframe = reloader_content.getElementsByTagName('iframe')[0]; + + if (document.getElementById("safari_remember_field").value != "" ) { + historyHash = document.getElementById("safari_remember_field").value.split(","); + } + + } + + if (browser.firefox) + { + var anchorDiv = document.createElement("div"); + anchorDiv.id = 'firefox_anchorDiv'; + document.body.appendChild(anchorDiv); + } + + //setTimeout(checkForUrlChange, 50); + } + + return { + historyHash: historyHash, + backStack: function() { return backStack; }, + forwardStack: function() { return forwardStack }, + getPlayer: getPlayer, + initialize: function(src) { + _initialize(src); + }, + setURL: function(url) { + document.location.href = url; + }, + getURL: function() { + return document.location.href; + }, + getTitle: function() { + return document.title; + }, + setTitle: function(title) { + try { + backStack[backStack.length - 1].title = title; + } catch(e) { } + //if on safari, set the title to be the empty string. + if (browser.safari) { + if (title == "") { + try { + var tmp = window.location.href.toString(); + title = tmp.substring((tmp.lastIndexOf("/")+1), tmp.lastIndexOf("#")); + } catch(e) { + title = ""; + } + } + } + document.title = title; + }, + setDefaultURL: function(def) + { + defaultHash = def; + def = getHash(); + //trailing ? is important else an extra frame gets added to the history + //when navigating back to the first page. Alternatively could check + //in history frame navigation to compare # and ?. + if (browser.ie) + { + window['_ie_firstload'] = true; + var sourceToSet = historyFrameSourcePrefix + def; + var func = function() { + getHistoryFrame().src = sourceToSet; + window.location.replace("#" + def); + setInterval(checkForUrlChange, 50); + } + try { + func(); + } catch(e) { + window.setTimeout(function() { func(); }, 0); + } + } + + if (browser.safari) + { + currentHistoryLength = history.length; + if (historyHash.length == 0) { + historyHash[currentHistoryLength] = def; + var newloc = "#" + def; + window.location.replace(newloc); + } else { + //alert(historyHash[historyHash.length-1]); + } + //setHash(def); + setInterval(checkForUrlChange, 50); + } + + + if (browser.firefox || browser.opera) + { + var reg = new RegExp("#" + def + "$"); + if (window.location.toString().match(reg)) { + } else { + var newloc ="#" + def; + window.location.replace(newloc); + } + setInterval(checkForUrlChange, 50); + //setHash(def); + } + + }, + + /* Set the current browser URL; called from inside BrowserManager to propagate + * the application state out to the container. + */ + setBrowserURL: function(flexAppUrl, objectId) { + if (browser.ie && typeof objectId != "undefined") { + currentObjectId = objectId; + } + //fromIframe = fromIframe || false; + //fromFlex = fromFlex || false; + //alert("setBrowserURL: " + flexAppUrl); + //flexAppUrl = (flexAppUrl == "") ? defaultHash : flexAppUrl ; + + var pos = document.location.href.indexOf('#'); + var baseUrl = pos != -1 ? document.location.href.substr(0, pos) : document.location.href; + var newUrl = baseUrl + '#' + flexAppUrl; + + if (document.location.href != newUrl && document.location.href + '#' != newUrl) { + currentHref = newUrl; + addHistoryEntry(baseUrl, newUrl, flexAppUrl); + currentHistoryLength = history.length; + } + }, + + browserURLChange: function(flexAppUrl) { + var objectId = null; + if (browser.ie && currentObjectId != null) { + objectId = currentObjectId; + } + pendingURL = ''; + + if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) { + var pl = getPlayers(); + for (var i = 0; i < pl.length; i++) { + try { + pl[i].browserURLChange(flexAppUrl); + } catch(e) { } + } + } else { + try { + getPlayer(objectId).browserURLChange(flexAppUrl); + } catch(e) { } + } + + currentObjectId = null; + }, + getUserAgent: function() { + return navigator.userAgent; + }, + getPlatform: function() { + return navigator.platform; + } + + } + +})(); + +// Initialization + +// Automated unit testing and other diagnostics + +function setURL(url) +{ + document.location.href = url; +} + +function backButton() +{ + history.back(); +} + +function forwardButton() +{ + history.forward(); +} + +function goForwardOrBackInHistory(step) +{ + history.go(step); +} + +//BrowserHistoryUtils.addEvent(window, "load", function() { BrowserHistory.initialize(); }); +(function(i) { + var u =navigator.userAgent;var e=/*@cc_on!@*/false; + var st = setTimeout; + if(/webkit/i.test(u)){ + st(function(){ + var dr=document.readyState; + if(dr=="loaded"||dr=="complete"){i()} + else{st(arguments.callee,10);}},10); + } else if((/mozilla/i.test(u)&&!/(compati)/.test(u)) || (/opera/i.test(u))){ + document.addEventListener("DOMContentLoaded",i,false); + } else if(e){ + (function(){ + var t=document.createElement('doc:rdy'); + try{t.doScroll('left'); + i();t=null; + }catch(e){st(arguments.callee,0);}})(); + } else{ + window.onload=i; + } +})( function() {BrowserHistory.initialize();} ); diff --git a/KRecordContainerFlex/html-template/history/historyFrame.html b/KRecordContainerFlex/html-template/history/historyFrame.html new file mode 100644 index 0000000..aebb8d8 --- /dev/null +++ b/KRecordContainerFlex/html-template/history/historyFrame.html @@ -0,0 +1,29 @@ + + + + + + + + Hidden frame for Browser History support. + + diff --git a/KRecordContainerFlex/html-template/index.template.html b/KRecordContainerFlex/html-template/index.template.html new file mode 100644 index 0000000..4dcd6ea --- /dev/null +++ b/KRecordContainerFlex/html-template/index.template.html @@ -0,0 +1,121 @@ + + + + + + + + + + + + +${title} + + + + + + + + + + + + + + + diff --git a/KRecordContainerFlex/html-template/locale.xml b/KRecordContainerFlex/html-template/locale.xml new file mode 100644 index 0000000..94bc76a --- /dev/null +++ b/KRecordContainerFlex/html-template/locale.xml @@ -0,0 +1,43 @@ + + + + Button.StopRecord + Click anywhere to stop recording + + + + Button.StartRecord + Click anywhere to start recording + + + + Button.Save + Save + + + + Button.Yes + Yes + + + + Button.No + No + + + + Dialog.Overwrite + Record again without saving? + + + + Dialog.Connecting + Connecting... + + + + Dialog.ConnectionError + Connection error. Please try again later + + + \ No newline at end of file diff --git a/KRecordContainerFlex/html-template/playerProductInstall.swf b/KRecordContainerFlex/html-template/playerProductInstall.swf new file mode 100644 index 0000000..bdc3437 Binary files /dev/null and b/KRecordContainerFlex/html-template/playerProductInstall.swf differ diff --git a/KRecordContainerFlex/html-template/skin.swf b/KRecordContainerFlex/html-template/skin.swf new file mode 100644 index 0000000..9e2724a Binary files /dev/null and b/KRecordContainerFlex/html-template/skin.swf differ diff --git a/KRecordContainerFlex/src/KRecordContainer.mxml b/KRecordContainerFlex/src/KRecordContainer.mxml new file mode 100644 index 0000000..ec07141 --- /dev/null +++ b/KRecordContainerFlex/src/KRecordContainer.mxml @@ -0,0 +1,43 @@ + + + + + + + + + + + diff --git a/KalturaRecord/.actionScriptProperties b/KalturaRecord/.actionScriptProperties new file mode 100644 index 0000000..15b8c2d --- /dev/null +++ b/KalturaRecord/.actionScriptProperties @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/KalturaRecord/.project b/KalturaRecord/.project new file mode 100644 index 0000000..5ba9834 --- /dev/null +++ b/KalturaRecord/.project @@ -0,0 +1,17 @@ + + + KalturaRecord + + + + + + com.adobe.flexbuilder.project.flexbuilder + + + + + + com.adobe.flexbuilder.project.actionscriptnature + + diff --git a/KalturaRecord/.settings/com.adobe.flexbuilder.project.prefs b/KalturaRecord/.settings/com.adobe.flexbuilder.project.prefs new file mode 100644 index 0000000..cb8d794 --- /dev/null +++ b/KalturaRecord/.settings/com.adobe.flexbuilder.project.prefs @@ -0,0 +1,3 @@ +#Mon Mar 21 16:39:03 IST 2011 +eclipse.preferences.version=1 +upgradeSDK/fb4= diff --git a/KalturaRecord/.settings/org.eclipse.ltk.core.refactoring.prefs b/KalturaRecord/.settings/org.eclipse.ltk.core.refactoring.prefs new file mode 100644 index 0000000..8e8bec9 --- /dev/null +++ b/KalturaRecord/.settings/org.eclipse.ltk.core.refactoring.prefs @@ -0,0 +1,3 @@ +#Mon Jun 27 15:35:05 IDT 2011 +eclipse.preferences.version=1 +org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false diff --git a/KalturaRecord/bin-debug/skin.swf b/KalturaRecord/bin-debug/skin.swf new file mode 100644 index 0000000..97a444a Binary files /dev/null and b/KalturaRecord/bin-debug/skin.swf differ diff --git a/KalturaRecord/deliver/AC_OETags.js b/KalturaRecord/deliver/AC_OETags.js new file mode 100644 index 0000000..6366467 --- /dev/null +++ b/KalturaRecord/deliver/AC_OETags.js @@ -0,0 +1,292 @@ +// Flash Player Version Detection - Rev 1.6 +// Detect Client Browser type +// Copyright(c) 2005-2006 Adobe Macromedia Software, LLC. All rights reserved. +var isIE = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false; +var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false; +var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false; + +function ControlVersion() +{ + var version; + var axo; + var e; + + // NOTE : new ActiveXObject(strFoo) throws an exception if strFoo isn't in the registry + + try { + // version will be set for 7.X or greater players + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7"); + version = axo.GetVariable("$version"); + } catch (e) { + } + + if (!version) + { + try { + // version will be set for 6.X players only + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"); + + // installed player is some revision of 6.0 + // GetVariable("$version") crashes for versions 6.0.22 through 6.0.29, + // so we have to be careful. + + // default to the first public version + version = "WIN 6,0,21,0"; + + // throws if AllowScripAccess does not exist (introduced in 6.0r47) + axo.AllowScriptAccess = "always"; + + // safe to call for 6.0r47 or greater + version = axo.GetVariable("$version"); + + } catch (e) { + } + } + + if (!version) + { + try { + // version will be set for 4.X or 5.X player + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3"); + version = axo.GetVariable("$version"); + } catch (e) { + } + } + + if (!version) + { + try { + // version will be set for 3.X player + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3"); + version = "WIN 3,0,18,0"; + } catch (e) { + } + } + + if (!version) + { + try { + // version will be set for 2.X player + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); + version = "WIN 2,0,0,11"; + } catch (e) { + version = -1; + } + } + + return version; +} + +// JavaScript helper required to detect Flash Player PlugIn version information +function GetSwfVer(){ + // NS/Opera version >= 3 check for Flash plugin in plugin array + var flashVer = -1; + + if (navigator.plugins != null && navigator.plugins.length > 0) { + if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) { + var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : ""; + var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description; + var descArray = flashDescription.split(" "); + var tempArrayMajor = descArray[2].split("."); + var versionMajor = tempArrayMajor[0]; + var versionMinor = tempArrayMajor[1]; + var versionRevision = descArray[3]; + if (versionRevision == "") { + versionRevision = descArray[4]; + } + if (versionRevision[0] == "d") { + versionRevision = versionRevision.substring(1); + } else if (versionRevision[0] == "r") { + versionRevision = versionRevision.substring(1); + if (versionRevision.indexOf("d") > 0) { + versionRevision = versionRevision.substring(0, versionRevision.indexOf("d")); + } + } else if (versionRevision[0] == "b") { + versionRevision = versionRevision.substring(1); + } + var flashVer = versionMajor + "." + versionMinor + "." + versionRevision; + } + } + // MSN/WebTV 2.6 supports Flash 4 + else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4; + // WebTV 2.5 supports Flash 3 + else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3; + // older WebTV supports Flash 2 + else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2; + else if ( isIE && isWin && !isOpera ) { + flashVer = ControlVersion(); + } + return flashVer; +} + +// When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available +function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision) +{ + versionStr = GetSwfVer(); + if (versionStr == -1 ) { + return false; + } else if (versionStr != 0) { + if(isIE && isWin && !isOpera) { + // Given "WIN 2,0,0,11" + tempArray = versionStr.split(" "); // ["WIN", "2,0,0,11"] + tempString = tempArray[1]; // "2,0,0,11" + versionArray = tempString.split(","); // ['2', '0', '0', '11'] + } else { + versionArray = versionStr.split("."); + } + var versionMajor = versionArray[0]; + var versionMinor = versionArray[1]; + var versionRevision = versionArray[2]; + + // is the major.revision >= requested major.revision AND the minor version >= requested minor + if (versionMajor > parseFloat(reqMajorVer)) { + return true; + } else if (versionMajor == parseFloat(reqMajorVer)) { + if (versionMinor > parseFloat(reqMinorVer)) + return true; + else if (versionMinor == parseFloat(reqMinorVer)) { + if (versionRevision >= parseFloat(reqRevision)) + return true; + } + } + return false; + } +} + +function AC_AddExtension(src, ext) +{ + var qIndex = src.indexOf('?'); + if ( qIndex != -1) + { + // Add the extention (if needed) before the query params + var path = src.substring(0, qIndex); + if (path.length >= ext.length && path.lastIndexOf(ext) == (path.length - ext.length)) + return src; + else + return src.replace(/\?/, ext+'?'); + } + else + { + // Add the extension (if needed) to the end of the URL + if (src.length >= ext.length && src.lastIndexOf(ext) == (src.length - ext.length)) + return src; // Already have extension + else + return src + ext; + } +} + +function AC_Generateobj(objAttrs, params, embedAttrs) +{ + var str = ''; + if (isIE && isWin && !isOpera) + { + str += ' '; + str += ''; + } else { + str += ' + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/KalturaRecord/deliver/KRecord.swf b/KalturaRecord/deliver/KRecord.swf new file mode 100644 index 0000000..fcfeb14 Binary files /dev/null and b/KalturaRecord/deliver/KRecord.swf differ diff --git a/KalturaRecord/deliver/deliver.rar b/KalturaRecord/deliver/deliver.rar new file mode 100644 index 0000000..cde98c2 Binary files /dev/null and b/KalturaRecord/deliver/deliver.rar differ diff --git a/KalturaRecord/deliver/kaltura_client.php b/KalturaRecord/deliver/kaltura_client.php new file mode 100644 index 0000000..14c8e78 --- /dev/null +++ b/KalturaRecord/deliver/kaltura_client.php @@ -0,0 +1,1113 @@ +. +*/ + +require_once("kaltura_client_base.php"); + +class KalturaEntry +{ + public $name; + public $tags; + public $type; + public $mediaType; + public $source; + public $sourceId; + public $sourceLink; + public $licenseType; + public $credit; + public $groupId; + public $partnerData; + public $conversionQuality; + public $permissions; + public $dataContent; + public $desiredVersion; + public $url; + public $thumbUrl; + public $filename; + public $realFilename; + public $indexedCustomData1; + public $thumbOffset; +} + +class KalturaKShow +{ + public $name; + public $description; + public $tags; + public $indexedCustomData3; + public $groupId; + public $permissions; + public $partnerData; + public $allowQuickEdit; +} + +class KalturaModeration +{ + public $comments; + public $objectType; + public $objectId; +} + +class KalturaUser +{ + public $screenName; + public $fullName; + public $email; + public $dateOfBirth; + public $aboutMe; + public $tags; + public $gender; + public $country; + public $state; + public $city; + public $zip; + public $urlList; + public $networkHighschool; + public $networkCollege; + public $partnerData; +} + +class KalturaWidget +{ + public $kshowId; + public $entryId; + public $sourceWidgetId; + public $uiConfId; + public $customData; + public $partnerData; + public $securityType; +} + +class KalturaPuserKuser +{ +} + +class KalturaUiConf +{ + public $name; +} + +class KalturaEntryFilter +{ + const ORDER_BY_CREATED_AT_ASC = "+created_at"; + const ORDER_BY_CREATED_AT_DESC = "-created_at"; + const ORDER_BY_VIEWS_ASC = "+views"; + const ORDER_BY_VIEWS_DESC = "-views"; + const ORDER_BY_ID_ASC = "+id"; + const ORDER_BY_ID_DESC = "-id"; + + public $equalUserId; + public $equalKshowId; + public $equalType; + public $inType; + public $equalMediaType; + public $inMediaType; + public $equalIndexedCustomData; + public $inIndexedCustomData; + public $likeName; + public $equalGroupId; + public $greaterThanOrEqualViews; + public $greaterThanOrEqualCreatedAt; + public $lessThanOrEqualCreatedAt; + public $inPartnerId; + public $equalPartnerId; + public $orderBy; +} + +class KalturaKShowFilter +{ + const ORDER_BY_CREATED_AT_ASC = "+created_at"; + const ORDER_BY_CREATED_AT_DESC = "-created_at"; + const ORDER_BY_VIEWS_ASC = "+views"; + const ORDER_BY_VIEWS_DESC = "-views"; + const ORDER_BY_ID_ASC = "+id"; + const ORDER_BY_ID_DESC = "-id"; + + public $greaterThanOrEqualViews; + public $equalType; + public $equalProducerId; + public $greaterThanOrEqualCreatedAt; + public $lessThanOrEqualCreatedAt; + public $orderBy; +} + +class KalturaModerationFilter +{ + const ORDER_BY_ID_ASC = "+id"; + const ORDER_BY_ID_DESC = "-id"; + + public $equalId; + public $equalPuserId; + public $equalStatus; + public $likeComments; + public $equalObjectId; + public $equalObjectType; + public $equalGroupId; + public $orderBy; +} + +class KalturaNotificationFilter +{ + const ORDER_BY_ID_ASC = "+id"; + const ORDER_BY_ID_DESC = "-id"; + + public $equalId; + public $greaterThanOrEqualId; + public $equalStatus; + public $equalType; + public $orderBy; +} + +class KalturaNotification +{ + public $id; + public $status; + public $notificationResult; +} + +class KalturaPartner +{ + public $name; + public $url1; + public $url2; + public $appearInSearch; + public $adminName; + public $adminEmail; + public $description; + public $commercialUse; +} + +class KalturaClient extends KalturaClientBase +{ + public function __constructor() + { + parent::__constructor(); + } + + public function addDvdEntry(KalturaSessionUser $kalturaSessionUser, KalturaEntry $dvdEntry) + { + $params = array(); + $this->addOptionalParam($params, "dvdEntry_name", $dvdEntry->name); + $this->addOptionalParam($params, "dvdEntry_tags", $dvdEntry->tags); + $this->addOptionalParam($params, "dvdEntry_type", $dvdEntry->type); + $this->addOptionalParam($params, "dvdEntry_mediaType", $dvdEntry->mediaType); + $this->addOptionalParam($params, "dvdEntry_source", $dvdEntry->source); + $this->addOptionalParam($params, "dvdEntry_sourceId", $dvdEntry->sourceId); + $this->addOptionalParam($params, "dvdEntry_sourceLink", $dvdEntry->sourceLink); + $this->addOptionalParam($params, "dvdEntry_licenseType", $dvdEntry->licenseType); + $this->addOptionalParam($params, "dvdEntry_credit", $dvdEntry->credit); + $this->addOptionalParam($params, "dvdEntry_groupId", $dvdEntry->groupId); + $this->addOptionalParam($params, "dvdEntry_partnerData", $dvdEntry->partnerData); + $this->addOptionalParam($params, "dvdEntry_conversionQuality", $dvdEntry->conversionQuality); + $this->addOptionalParam($params, "dvdEntry_permissions", $dvdEntry->permissions); + $this->addOptionalParam($params, "dvdEntry_dataContent", $dvdEntry->dataContent); + $this->addOptionalParam($params, "dvdEntry_desiredVersion", $dvdEntry->desiredVersion); + $this->addOptionalParam($params, "dvdEntry_url", $dvdEntry->url); + $this->addOptionalParam($params, "dvdEntry_thumbUrl", $dvdEntry->thumbUrl); + $this->addOptionalParam($params, "dvdEntry_filename", $dvdEntry->filename); + $this->addOptionalParam($params, "dvdEntry_realFilename", $dvdEntry->realFilename); + $this->addOptionalParam($params, "dvdEntry_indexedCustomData1", $dvdEntry->indexedCustomData1); + $this->addOptionalParam($params, "dvdEntry_thumbOffset", $dvdEntry->thumbOffset); + + $result = $this->hit("adddvdentry", $kalturaSessionUser, $params); + return $result; + } + + public function addEntry(KalturaSessionUser $kalturaSessionUser, $kshowId, KalturaEntry $entry, $uid = null) + { + $params = array(); + $params["kshow_id"] = $kshowId; + $this->addOptionalParam($params, "entry_name", $entry->name); + $this->addOptionalParam($params, "entry_tags", $entry->tags); + $this->addOptionalParam($params, "entry_type", $entry->type); + $this->addOptionalParam($params, "entry_mediaType", $entry->mediaType); + $this->addOptionalParam($params, "entry_source", $entry->source); + $this->addOptionalParam($params, "entry_sourceId", $entry->sourceId); + $this->addOptionalParam($params, "entry_sourceLink", $entry->sourceLink); + $this->addOptionalParam($params, "entry_licenseType", $entry->licenseType); + $this->addOptionalParam($params, "entry_credit", $entry->credit); + $this->addOptionalParam($params, "entry_groupId", $entry->groupId); + $this->addOptionalParam($params, "entry_partnerData", $entry->partnerData); + $this->addOptionalParam($params, "entry_conversionQuality", $entry->conversionQuality); + $this->addOptionalParam($params, "entry_permissions", $entry->permissions); + $this->addOptionalParam($params, "entry_dataContent", $entry->dataContent); + $this->addOptionalParam($params, "entry_desiredVersion", $entry->desiredVersion); + $this->addOptionalParam($params, "entry_url", $entry->url); + $this->addOptionalParam($params, "entry_thumbUrl", $entry->thumbUrl); + $this->addOptionalParam($params, "entry_filename", $entry->filename); + $this->addOptionalParam($params, "entry_realFilename", $entry->realFilename); + $this->addOptionalParam($params, "entry_indexedCustomData1", $entry->indexedCustomData1); + $this->addOptionalParam($params, "entry_thumbOffset", $entry->thumbOffset); + $this->addOptionalParam($params, "uid", $uid); + + $result = $this->hit("addentry", $kalturaSessionUser, $params); + return $result; + } + + public function addKShow(KalturaSessionUser $kalturaSessionUser, KalturaKShow $kshow, $detailed = null, $allowDuplicateNames = null) + { + $params = array(); + $this->addOptionalParam($params, "kshow_name", $kshow->name); + $this->addOptionalParam($params, "kshow_description", $kshow->description); + $this->addOptionalParam($params, "kshow_tags", $kshow->tags); + $this->addOptionalParam($params, "kshow_indexedCustomData3", $kshow->indexedCustomData3); + $this->addOptionalParam($params, "kshow_groupId", $kshow->groupId); + $this->addOptionalParam($params, "kshow_permissions", $kshow->permissions); + $this->addOptionalParam($params, "kshow_partnerData", $kshow->partnerData); + $this->addOptionalParam($params, "kshow_allowQuickEdit", $kshow->allowQuickEdit); + $this->addOptionalParam($params, "detailed", $detailed); + $this->addOptionalParam($params, "allow_duplicate_names", $allowDuplicateNames); + + $result = $this->hit("addkshow", $kalturaSessionUser, $params); + return $result; + } + + public function addModeration(KalturaSessionUser $kalturaSessionUser, KalturaModeration $moderation) + { + $params = array(); + $this->addOptionalParam($params, "moderation_comments", $moderation->comments); + $this->addOptionalParam($params, "moderation_objectType", $moderation->objectType); + $this->addOptionalParam($params, "moderation_objectId", $moderation->objectId); + + $result = $this->hit("addmoderation", $kalturaSessionUser, $params); + return $result; + } + + public function addPartnerEntry(KalturaSessionUser $kalturaSessionUser, $kshowId, KalturaEntry $entry, $uid = null) + { + $params = array(); + $params["kshow_id"] = $kshowId; + $this->addOptionalParam($params, "entry_name", $entry->name); + $this->addOptionalParam($params, "entry_tags", $entry->tags); + $this->addOptionalParam($params, "entry_type", $entry->type); + $this->addOptionalParam($params, "entry_mediaType", $entry->mediaType); + $this->addOptionalParam($params, "entry_source", $entry->source); + $this->addOptionalParam($params, "entry_sourceId", $entry->sourceId); + $this->addOptionalParam($params, "entry_sourceLink", $entry->sourceLink); + $this->addOptionalParam($params, "entry_licenseType", $entry->licenseType); + $this->addOptionalParam($params, "entry_credit", $entry->credit); + $this->addOptionalParam($params, "entry_groupId", $entry->groupId); + $this->addOptionalParam($params, "entry_partnerData", $entry->partnerData); + $this->addOptionalParam($params, "entry_conversionQuality", $entry->conversionQuality); + $this->addOptionalParam($params, "entry_permissions", $entry->permissions); + $this->addOptionalParam($params, "entry_dataContent", $entry->dataContent); + $this->addOptionalParam($params, "entry_desiredVersion", $entry->desiredVersion); + $this->addOptionalParam($params, "entry_url", $entry->url); + $this->addOptionalParam($params, "entry_thumbUrl", $entry->thumbUrl); + $this->addOptionalParam($params, "entry_filename", $entry->filename); + $this->addOptionalParam($params, "entry_realFilename", $entry->realFilename); + $this->addOptionalParam($params, "entry_indexedCustomData1", $entry->indexedCustomData1); + $this->addOptionalParam($params, "entry_thumbOffset", $entry->thumbOffset); + $this->addOptionalParam($params, "uid", $uid); + + $result = $this->hit("addpartnerentry", $kalturaSessionUser, $params); + return $result; + } + + public function addUser(KalturaSessionUser $kalturaSessionUser, $userId, KalturaUser $user) + { + $params = array(); + $params["user_id"] = $userId; + $this->addOptionalParam($params, "user_screenName", $user->screenName); + $this->addOptionalParam($params, "user_fullName", $user->fullName); + $this->addOptionalParam($params, "user_email", $user->email); + $this->addOptionalParam($params, "user_dateOfBirth", $user->dateOfBirth); + $this->addOptionalParam($params, "user_aboutMe", $user->aboutMe); + $this->addOptionalParam($params, "user_tags", $user->tags); + $this->addOptionalParam($params, "user_gender", $user->gender); + $this->addOptionalParam($params, "user_country", $user->country); + $this->addOptionalParam($params, "user_state", $user->state); + $this->addOptionalParam($params, "user_city", $user->city); + $this->addOptionalParam($params, "user_zip", $user->zip); + $this->addOptionalParam($params, "user_urlList", $user->urlList); + $this->addOptionalParam($params, "user_networkHighschool", $user->networkHighschool); + $this->addOptionalParam($params, "user_networkCollege", $user->networkCollege); + $this->addOptionalParam($params, "user_partnerData", $user->partnerData); + + $result = $this->hit("adduser", $kalturaSessionUser, $params); + return $result; + } + + public function addWidget(KalturaSessionUser $kalturaSessionUser, KalturaWidget $widget) + { + $params = array(); + $this->addOptionalParam($params, "widget_kshowId", $widget->kshowId); + $this->addOptionalParam($params, "widget_entryId", $widget->entryId); + $this->addOptionalParam($params, "widget_sourceWidgetId", $widget->sourceWidgetId); + $this->addOptionalParam($params, "widget_uiConfId", $widget->uiConfId); + $this->addOptionalParam($params, "widget_customData", $widget->customData); + $this->addOptionalParam($params, "widget_partnerData", $widget->partnerData); + $this->addOptionalParam($params, "widget_securityType", $widget->securityType); + + $result = $this->hit("addwidget", $kalturaSessionUser, $params); + return $result; + } + + public function checkNotifications(KalturaSessionUser $kalturaSessionUser, $notificationIds, $separator = ",", $detailed = null) + { + $params = array(); + $params["notification_ids"] = $notificationIds; + $this->addOptionalParam($params, "separator", $separator); + $this->addOptionalParam($params, "detailed", $detailed); + + $result = $this->hit("checknotifications", $kalturaSessionUser, $params); + return $result; + } + + public function cloneKShow(KalturaSessionUser $kalturaSessionUser, $kshowId, $detailed = null) + { + $params = array(); + $params["kshow_id"] = $kshowId; + $this->addOptionalParam($params, "detailed", $detailed); + + $result = $this->hit("clonekshow", $kalturaSessionUser, $params); + return $result; + } + + public function collectStats(KalturaSessionUser $kalturaSessionUser, $objType, $objId, $command, $value, $extraInfo, $kshowId = null) + { + $params = array(); + $params["obj_type"] = $objType; + $params["obj_id"] = $objId; + $params["command"] = $command; + $params["value"] = $value; + $params["extra_info"] = $extraInfo; + $this->addOptionalParam($params, "kshow_id", $kshowId); + + $result = $this->hit("collectstats", $kalturaSessionUser, $params); + return $result; + } + + public function deleteEntry(KalturaSessionUser $kalturaSessionUser, $entryId, $kshowId = null) + { + $params = array(); + $params["entry_id"] = $entryId; + $this->addOptionalParam($params, "kshow_id", $kshowId); + + $result = $this->hit("deleteentry", $kalturaSessionUser, $params); + return $result; + } + + public function deleteKShow(KalturaSessionUser $kalturaSessionUser, $kshowId) + { + $params = array(); + $params["kshow_id"] = $kshowId; + + $result = $this->hit("deletekshow", $kalturaSessionUser, $params); + return $result; + } + + public function deleteUser(KalturaSessionUser $kalturaSessionUser, $userId) + { + $params = array(); + $params["user_id"] = $userId; + + $result = $this->hit("deleteuser", $kalturaSessionUser, $params); + return $result; + } + + public function getAllEntries(KalturaSessionUser $kalturaSessionUser, $entryId, $kshowId, $listType = null, $version = null) + { + $params = array(); + $params["entry_id"] = $entryId; + $params["kshow_id"] = $kshowId; + $this->addOptionalParam($params, "list_type", $listType); + $this->addOptionalParam($params, "version", $version); + + $result = $this->hit("getallentries", $kalturaSessionUser, $params); + return $result; + } + + public function getDvdEntry(KalturaSessionUser $kalturaSessionUser, $dvdEntryId, $detailed = null) + { + $params = array(); + $params["dvdEntry_id"] = $dvdEntryId; + $this->addOptionalParam($params, "detailed", $detailed); + + $result = $this->hit("getdvdentry", $kalturaSessionUser, $params); + return $result; + } + + public function getEntries(KalturaSessionUser $kalturaSessionUser, $entryIds, $separator = ",", $detailed = null) + { + $params = array(); + $params["entry_ids"] = $entryIds; + $this->addOptionalParam($params, "separator", $separator); + $this->addOptionalParam($params, "detailed", $detailed); + + $result = $this->hit("getentries", $kalturaSessionUser, $params); + return $result; + } + + public function getEntry(KalturaSessionUser $kalturaSessionUser, $entryId, $detailed = null, $version = null) + { + $params = array(); + $params["entry_id"] = $entryId; + $this->addOptionalParam($params, "detailed", $detailed); + $this->addOptionalParam($params, "version", $version); + + $result = $this->hit("getentry", $kalturaSessionUser, $params); + return $result; + } + + public function getKShow(KalturaSessionUser $kalturaSessionUser, $kshowId, $detailed = null) + { + $params = array(); + $params["kshow_id"] = $kshowId; + $this->addOptionalParam($params, "detailed", $detailed); + + $result = $this->hit("getkshow", $kalturaSessionUser, $params); + return $result; + } + + public function getLastVersionsInfo(KalturaSessionUser $kalturaSessionUser, $kshowId) + { + $params = array(); + $params["kshow_id"] = $kshowId; + + $result = $this->hit("getlastversionsinfo", $kalturaSessionUser, $params); + return $result; + } + + public function getMetaDataAction(KalturaSessionUser $kalturaSessionUser, $entryId, $kshowId, $version) + { + $params = array(); + $params["entry_id"] = $entryId; + $params["kshow_id"] = $kshowId; + $params["version"] = $version; + + $result = $this->hit("getmetadata", $kalturaSessionUser, $params); + return $result; + } + + public function getPartner(KalturaSessionUser $kalturaSessionUser, $partnerAdminEmail, $cmsPassword, $partnerId) + { + $params = array(); + $params["partner_adminEmail"] = $partnerAdminEmail; + $params["cms_password"] = $cmsPassword; + $params["partner_id"] = $partnerId; + + $result = $this->hit("getpartner", $kalturaSessionUser, $params); + return $result; + } + + public function getThumbnail(KalturaSessionUser $kalturaSessionUser, $filename) + { + $params = array(); + $params["filename"] = $filename; + + $result = $this->hit("getthumbnail", $kalturaSessionUser, $params); + return $result; + } + + public function getUIConf(KalturaSessionUser $kalturaSessionUser, $uiConfId, $detailed = null) + { + $params = array(); + $params["ui_conf_id"] = $uiConfId; + $this->addOptionalParam($params, "detailed", $detailed); + + $result = $this->hit("getuiconf", $kalturaSessionUser, $params); + return $result; + } + + public function getUser(KalturaSessionUser $kalturaSessionUser, $userId, $detailed = null) + { + $params = array(); + $params["user_id"] = $userId; + $this->addOptionalParam($params, "detailed", $detailed); + + $result = $this->hit("getuser", $kalturaSessionUser, $params); + return $result; + } + + public function getWidget(KalturaSessionUser $kalturaSessionUser, $widgetId, $detailed = null) + { + $params = array(); + $params["widget_id"] = $widgetId; + $this->addOptionalParam($params, "detailed", $detailed); + + $result = $this->hit("getwidget", $kalturaSessionUser, $params); + return $result; + } + + public function handleModeration(KalturaSessionUser $kalturaSessionUser, $moderationId, $moderationStatus) + { + $params = array(); + $params["moderation_id"] = $moderationId; + $params["moderation_status"] = $moderationStatus; + + $result = $this->hit("handlemoderation", $kalturaSessionUser, $params); + return $result; + } + + public function listDvdEntries(KalturaSessionUser $kalturaSessionUser, KalturaEntryFilter $filter, $detailed = null, $pageSize = 10, $page = 1, $useFilterPuserId = null) + { + $params = array(); + $this->addOptionalParam($params, "filter__eq_user_id", $filter->equalUserId); + $this->addOptionalParam($params, "filter__eq_kshow_id", $filter->equalKshowId); + $this->addOptionalParam($params, "filter__eq_type", $filter->equalType); + $this->addOptionalParam($params, "filter__in_type", $filter->inType); + $this->addOptionalParam($params, "filter__eq_media_type", $filter->equalMediaType); + $this->addOptionalParam($params, "filter__in_media_type", $filter->inMediaType); + $this->addOptionalParam($params, "filter__eq_indexed_custom_data_1", $filter->equalIndexedCustomData); + $this->addOptionalParam($params, "filter__in_indexed_custom_data_1", $filter->inIndexedCustomData); + $this->addOptionalParam($params, "filter__like_name", $filter->likeName); + $this->addOptionalParam($params, "filter__eq_group_id", $filter->equalGroupId); + $this->addOptionalParam($params, "filter__gte_views", $filter->greaterThanOrEqualViews); + $this->addOptionalParam($params, "filter__gte_created_at", $filter->greaterThanOrEqualCreatedAt); + $this->addOptionalParam($params, "filter__lte_created_at", $filter->lessThanOrEqualCreatedAt); + $this->addOptionalParam($params, "filter__in_partner_id", $filter->inPartnerId); + $this->addOptionalParam($params, "filter__eq_partner_id", $filter->equalPartnerId); + $this->addOptionalParam($params, "filter__order_by", $filter->orderBy); + $this->addOptionalParam($params, "detailed", $detailed); + $this->addOptionalParam($params, "page_size", $pageSize); + $this->addOptionalParam($params, "page", $page); + $this->addOptionalParam($params, "use_filter_puser_id", $useFilterPuserId); + + $result = $this->hit("listdvdentries", $kalturaSessionUser, $params); + return $result; + } + + public function listEntries(KalturaSessionUser $kalturaSessionUser, KalturaEntryFilter $filter, $detailed = null, $pageSize = 10, $page = 1, $useFilterPuserId = null) + { + $params = array(); + $this->addOptionalParam($params, "filter__eq_user_id", $filter->equalUserId); + $this->addOptionalParam($params, "filter__eq_kshow_id", $filter->equalKshowId); + $this->addOptionalParam($params, "filter__eq_type", $filter->equalType); + $this->addOptionalParam($params, "filter__in_type", $filter->inType); + $this->addOptionalParam($params, "filter__eq_media_type", $filter->equalMediaType); + $this->addOptionalParam($params, "filter__in_media_type", $filter->inMediaType); + $this->addOptionalParam($params, "filter__eq_indexed_custom_data_1", $filter->equalIndexedCustomData); + $this->addOptionalParam($params, "filter__in_indexed_custom_data_1", $filter->inIndexedCustomData); + $this->addOptionalParam($params, "filter__like_name", $filter->likeName); + $this->addOptionalParam($params, "filter__eq_group_id", $filter->equalGroupId); + $this->addOptionalParam($params, "filter__gte_views", $filter->greaterThanOrEqualViews); + $this->addOptionalParam($params, "filter__gte_created_at", $filter->greaterThanOrEqualCreatedAt); + $this->addOptionalParam($params, "filter__lte_created_at", $filter->lessThanOrEqualCreatedAt); + $this->addOptionalParam($params, "filter__in_partner_id", $filter->inPartnerId); + $this->addOptionalParam($params, "filter__eq_partner_id", $filter->equalPartnerId); + $this->addOptionalParam($params, "filter__order_by", $filter->orderBy); + $this->addOptionalParam($params, "detailed", $detailed); + $this->addOptionalParam($params, "page_size", $pageSize); + $this->addOptionalParam($params, "page", $page); + $this->addOptionalParam($params, "use_filter_puser_id", $useFilterPuserId); + + $result = $this->hit("listentries", $kalturaSessionUser, $params); + return $result; + } + + public function listKShows(KalturaSessionUser $kalturaSessionUser, KalturaKShowFilter $filter, $detailed = null, $pageSize = 10, $page = 1, $useFilterPuserId = null) + { + $params = array(); + $this->addOptionalParam($params, "filter__gte_views", $filter->greaterThanOrEqualViews); + $this->addOptionalParam($params, "filter__eq_type", $filter->equalType); + $this->addOptionalParam($params, "filter__eq_producer_id", $filter->equalProducerId); + $this->addOptionalParam($params, "filter__gte_created_at", $filter->greaterThanOrEqualCreatedAt); + $this->addOptionalParam($params, "filter__lte_created_at", $filter->lessThanOrEqualCreatedAt); + $this->addOptionalParam($params, "filter__order_by", $filter->orderBy); + $this->addOptionalParam($params, "detailed", $detailed); + $this->addOptionalParam($params, "page_size", $pageSize); + $this->addOptionalParam($params, "page", $page); + $this->addOptionalParam($params, "use_filter_puser_id", $useFilterPuserId); + + $result = $this->hit("listkshows", $kalturaSessionUser, $params); + return $result; + } + + public function listModerations(KalturaSessionUser $kalturaSessionUser, KalturaModerationFilter $filter, $detailed = null, $pageSize = 10, $page = 1) + { + $params = array(); + $this->addOptionalParam($params, "filter__eq_id", $filter->equalId); + $this->addOptionalParam($params, "filter__eq_puser_id", $filter->equalPuserId); + $this->addOptionalParam($params, "filter__eq_status", $filter->equalStatus); + $this->addOptionalParam($params, "filter__like_comments", $filter->likeComments); + $this->addOptionalParam($params, "filter__eq_object_id", $filter->equalObjectId); + $this->addOptionalParam($params, "filter__eq_object_type", $filter->equalObjectType); + $this->addOptionalParam($params, "filter__eq_group_id", $filter->equalGroupId); + $this->addOptionalParam($params, "filter__order_by", $filter->orderBy); + $this->addOptionalParam($params, "detailed", $detailed); + $this->addOptionalParam($params, "page_size", $pageSize); + $this->addOptionalParam($params, "page", $page); + + $result = $this->hit("listmoderations", $kalturaSessionUser, $params); + return $result; + } + + public function listMyDvdEntries(KalturaSessionUser $kalturaSessionUser, KalturaEntryFilter $filter, $detailed = null, $pageSize = 10, $page = 1, $useFilterPuserId = null) + { + $params = array(); + $this->addOptionalParam($params, "filter__eq_user_id", $filter->equalUserId); + $this->addOptionalParam($params, "filter__eq_kshow_id", $filter->equalKshowId); + $this->addOptionalParam($params, "filter__eq_type", $filter->equalType); + $this->addOptionalParam($params, "filter__in_type", $filter->inType); + $this->addOptionalParam($params, "filter__eq_media_type", $filter->equalMediaType); + $this->addOptionalParam($params, "filter__in_media_type", $filter->inMediaType); + $this->addOptionalParam($params, "filter__eq_indexed_custom_data_1", $filter->equalIndexedCustomData); + $this->addOptionalParam($params, "filter__in_indexed_custom_data_1", $filter->inIndexedCustomData); + $this->addOptionalParam($params, "filter__like_name", $filter->likeName); + $this->addOptionalParam($params, "filter__eq_group_id", $filter->equalGroupId); + $this->addOptionalParam($params, "filter__gte_views", $filter->greaterThanOrEqualViews); + $this->addOptionalParam($params, "filter__gte_created_at", $filter->greaterThanOrEqualCreatedAt); + $this->addOptionalParam($params, "filter__lte_created_at", $filter->lessThanOrEqualCreatedAt); + $this->addOptionalParam($params, "filter__in_partner_id", $filter->inPartnerId); + $this->addOptionalParam($params, "filter__eq_partner_id", $filter->equalPartnerId); + $this->addOptionalParam($params, "filter__order_by", $filter->orderBy); + $this->addOptionalParam($params, "detailed", $detailed); + $this->addOptionalParam($params, "page_size", $pageSize); + $this->addOptionalParam($params, "page", $page); + $this->addOptionalParam($params, "use_filter_puser_id", $useFilterPuserId); + + $result = $this->hit("listmydvdentries", $kalturaSessionUser, $params); + return $result; + } + + public function listMyEntries(KalturaSessionUser $kalturaSessionUser, KalturaEntryFilter $filter, $detailed = null, $pageSize = 10, $page = 1, $useFilterPuserId = null) + { + $params = array(); + $this->addOptionalParam($params, "filter__eq_user_id", $filter->equalUserId); + $this->addOptionalParam($params, "filter__eq_kshow_id", $filter->equalKshowId); + $this->addOptionalParam($params, "filter__eq_type", $filter->equalType); + $this->addOptionalParam($params, "filter__in_type", $filter->inType); + $this->addOptionalParam($params, "filter__eq_media_type", $filter->equalMediaType); + $this->addOptionalParam($params, "filter__in_media_type", $filter->inMediaType); + $this->addOptionalParam($params, "filter__eq_indexed_custom_data_1", $filter->equalIndexedCustomData); + $this->addOptionalParam($params, "filter__in_indexed_custom_data_1", $filter->inIndexedCustomData); + $this->addOptionalParam($params, "filter__like_name", $filter->likeName); + $this->addOptionalParam($params, "filter__eq_group_id", $filter->equalGroupId); + $this->addOptionalParam($params, "filter__gte_views", $filter->greaterThanOrEqualViews); + $this->addOptionalParam($params, "filter__gte_created_at", $filter->greaterThanOrEqualCreatedAt); + $this->addOptionalParam($params, "filter__lte_created_at", $filter->lessThanOrEqualCreatedAt); + $this->addOptionalParam($params, "filter__in_partner_id", $filter->inPartnerId); + $this->addOptionalParam($params, "filter__eq_partner_id", $filter->equalPartnerId); + $this->addOptionalParam($params, "filter__order_by", $filter->orderBy); + $this->addOptionalParam($params, "detailed", $detailed); + $this->addOptionalParam($params, "page_size", $pageSize); + $this->addOptionalParam($params, "page", $page); + $this->addOptionalParam($params, "use_filter_puser_id", $useFilterPuserId); + + $result = $this->hit("listmyentries", $kalturaSessionUser, $params); + return $result; + } + + public function listMyKShows(KalturaSessionUser $kalturaSessionUser, KalturaKShowFilter $filter, $detailed = null, $pageSize = 10, $page = 1, $useFilterPuserId = null) + { + $params = array(); + $this->addOptionalParam($params, "filter__gte_views", $filter->greaterThanOrEqualViews); + $this->addOptionalParam($params, "filter__eq_type", $filter->equalType); + $this->addOptionalParam($params, "filter__eq_producer_id", $filter->equalProducerId); + $this->addOptionalParam($params, "filter__gte_created_at", $filter->greaterThanOrEqualCreatedAt); + $this->addOptionalParam($params, "filter__lte_created_at", $filter->lessThanOrEqualCreatedAt); + $this->addOptionalParam($params, "filter__order_by", $filter->orderBy); + $this->addOptionalParam($params, "detailed", $detailed); + $this->addOptionalParam($params, "page_size", $pageSize); + $this->addOptionalParam($params, "page", $page); + $this->addOptionalParam($params, "use_filter_puser_id", $useFilterPuserId); + + $result = $this->hit("listmykshows", $kalturaSessionUser, $params); + return $result; + } + + public function listNotifications(KalturaSessionUser $kalturaSessionUser, KalturaNotificationFilter $filter, $pageSize = 10, $page = 1) + { + $params = array(); + $this->addOptionalParam($params, "filter__eq_id", $filter->equalId); + $this->addOptionalParam($params, "filter__gte_id", $filter->greaterThanOrEqualId); + $this->addOptionalParam($params, "filter__eq_status", $filter->equalStatus); + $this->addOptionalParam($params, "filter__eq_type", $filter->equalType); + $this->addOptionalParam($params, "filter__order_by", $filter->orderBy); + $this->addOptionalParam($params, "page_size", $pageSize); + $this->addOptionalParam($params, "page", $page); + + $result = $this->hit("listnotifications", $kalturaSessionUser, $params); + return $result; + } + + public function listPartnerEntries(KalturaSessionUser $kalturaSessionUser, KalturaEntryFilter $filter, $detailed = null, $pageSize = 10, $page = 1, $useFilterPuserId = null) + { + $params = array(); + $this->addOptionalParam($params, "filter__eq_user_id", $filter->equalUserId); + $this->addOptionalParam($params, "filter__eq_kshow_id", $filter->equalKshowId); + $this->addOptionalParam($params, "filter__eq_type", $filter->equalType); + $this->addOptionalParam($params, "filter__in_type", $filter->inType); + $this->addOptionalParam($params, "filter__eq_media_type", $filter->equalMediaType); + $this->addOptionalParam($params, "filter__in_media_type", $filter->inMediaType); + $this->addOptionalParam($params, "filter__eq_indexed_custom_data_1", $filter->equalIndexedCustomData); + $this->addOptionalParam($params, "filter__in_indexed_custom_data_1", $filter->inIndexedCustomData); + $this->addOptionalParam($params, "filter__like_name", $filter->likeName); + $this->addOptionalParam($params, "filter__eq_group_id", $filter->equalGroupId); + $this->addOptionalParam($params, "filter__gte_views", $filter->greaterThanOrEqualViews); + $this->addOptionalParam($params, "filter__gte_created_at", $filter->greaterThanOrEqualCreatedAt); + $this->addOptionalParam($params, "filter__lte_created_at", $filter->lessThanOrEqualCreatedAt); + $this->addOptionalParam($params, "filter__in_partner_id", $filter->inPartnerId); + $this->addOptionalParam($params, "filter__eq_partner_id", $filter->equalPartnerId); + $this->addOptionalParam($params, "filter__order_by", $filter->orderBy); + $this->addOptionalParam($params, "detailed", $detailed); + $this->addOptionalParam($params, "page_size", $pageSize); + $this->addOptionalParam($params, "page", $page); + $this->addOptionalParam($params, "use_filter_puser_id", $useFilterPuserId); + + $result = $this->hit("listpartnerentries", $kalturaSessionUser, $params); + return $result; + } + + public function rankKShow(KalturaSessionUser $kalturaSessionUser, $kshowId, $rank, $pageSize = 10, $page = 1) + { + $params = array(); + $params["kshow_id"] = $kshowId; + $params["rank"] = $rank; + $this->addOptionalParam($params, "page_size", $pageSize); + $this->addOptionalParam($params, "page", $page); + + $result = $this->hit("rankkshow", $kalturaSessionUser, $params); + return $result; + } + + public function registerPartner(KalturaSessionUser $kalturaSessionUser, KalturaPartner $partner, $cmsPassword = null) + { + $params = array(); + $this->addOptionalParam($params, "partner_name", $partner->name); + $this->addOptionalParam($params, "partner_url1", $partner->url1); + $this->addOptionalParam($params, "partner_url2", $partner->url2); + $this->addOptionalParam($params, "partner_appearInSearch", $partner->appearInSearch); + $this->addOptionalParam($params, "partner_adminName", $partner->adminName); + $this->addOptionalParam($params, "partner_adminEmail", $partner->adminEmail); + $this->addOptionalParam($params, "partner_description", $partner->description); + $this->addOptionalParam($params, "partner_commercialUse", $partner->commercialUse); + $this->addOptionalParam($params, "cms_password", $cmsPassword); + + $result = $this->hit("registerpartner", $kalturaSessionUser, $params); + return $result; + } + + public function reportEntry(KalturaSessionUser $kalturaSessionUser, KalturaModeration $moderation) + { + $params = array(); + $this->addOptionalParam($params, "moderation_comments", $moderation->comments); + $this->addOptionalParam($params, "moderation_objectType", $moderation->objectType); + $this->addOptionalParam($params, "moderation_objectId", $moderation->objectId); + + $result = $this->hit("reportentry", $kalturaSessionUser, $params); + return $result; + } + + public function reportKShow(KalturaSessionUser $kalturaSessionUser, KalturaModeration $moderation) + { + $params = array(); + $this->addOptionalParam($params, "moderation_comments", $moderation->comments); + $this->addOptionalParam($params, "moderation_objectType", $moderation->objectType); + $this->addOptionalParam($params, "moderation_objectId", $moderation->objectId); + + $result = $this->hit("reportkshow", $kalturaSessionUser, $params); + return $result; + } + + public function rollbackKShow(KalturaSessionUser $kalturaSessionUser, $kshowId, $kshowVersion) + { + $params = array(); + $params["kshow_id"] = $kshowId; + $params["kshow_version"] = $kshowVersion; + + $result = $this->hit("rollbackkshow", $kalturaSessionUser, $params); + return $result; + } + + public function search(KalturaSessionUser $kalturaSessionUser, $mediaType, $mediaSource, $search, $authData, $page = 1, $pageSize = 10) + { + $params = array(); + $params["media_type"] = $mediaType; + $params["media_source"] = $mediaSource; + $params["search"] = $search; + $params["auth_data"] = $authData; + $this->addOptionalParam($params, "page", $page); + $this->addOptionalParam($params, "page_size", $pageSize); + + $result = $this->hit("search", $kalturaSessionUser, $params); + return $result; + } + + public function searchAuthData(KalturaSessionUser $kalturaSessionUser, $mediaSource, $username, $password) + { + $params = array(); + $params["media_source"] = $mediaSource; + $params["username"] = $username; + $params["password"] = $password; + + $result = $this->hit("searchauthdata", $kalturaSessionUser, $params); + return $result; + } + + public function searchFromUrl(KalturaSessionUser $kalturaSessionUser, $url, $mediaType) + { + $params = array(); + $params["url"] = $url; + $params["media_type"] = $mediaType; + + $result = $this->hit("searchfromurl", $kalturaSessionUser, $params); + return $result; + } + + public function searchMediaInfo(KalturaSessionUser $kalturaSessionUser) + { + $params = array(); + + $result = $this->hit("searchmediainfo", $kalturaSessionUser, $params); + return $result; + } + + public function searchmediaproviders(KalturaSessionUser $kalturaSessionUser) + { + $params = array(); + + $result = $this->hit("searchmediaproviders", $kalturaSessionUser, $params); + return $result; + } + + public function setMetaData(KalturaSessionUser $kalturaSessionUser, $entryId, $kshowId, $hasRoughCut, $xml) + { + $params = array(); + $params["entry_id"] = $entryId; + $params["kshow_id"] = $kshowId; + $params["HasRoughCut"] = $hasRoughCut; + $params["xml"] = $xml; + + $result = $this->hit("setmetadata", $kalturaSessionUser, $params); + return $result; + } + + public function startSession(KalturaSessionUser $kalturaSessionUser, $secret, $admin = null, $privileges = null, $expiry = 86400) + { + $params = array(); + $params["secret"] = $secret; + $this->addOptionalParam($params, "admin", $admin); + $this->addOptionalParam($params, "privileges", $privileges); + $this->addOptionalParam($params, "expiry", $expiry); + + $result = $this->hit("startsession", $kalturaSessionUser, $params); + return $result; + } + + public function startWidgetSession(KalturaSessionUser $kalturaSessionUser, $widgetId, $expiry = 86400) + { + $params = array(); + $params["widget_id"] = $widgetId; + $this->addOptionalParam($params, "expiry", $expiry); + + $result = $this->hit("startwidgetsession", $kalturaSessionUser, $params); + return $result; + } + + public function updateDvdEntry(KalturaSessionUser $kalturaSessionUser, $entryId, KalturaEntry $entry) + { + $params = array(); + $params["entry_id"] = $entryId; + $this->addOptionalParam($params, "entry_name", $entry->name); + $this->addOptionalParam($params, "entry_tags", $entry->tags); + $this->addOptionalParam($params, "entry_type", $entry->type); + $this->addOptionalParam($params, "entry_mediaType", $entry->mediaType); + $this->addOptionalParam($params, "entry_source", $entry->source); + $this->addOptionalParam($params, "entry_sourceId", $entry->sourceId); + $this->addOptionalParam($params, "entry_sourceLink", $entry->sourceLink); + $this->addOptionalParam($params, "entry_licenseType", $entry->licenseType); + $this->addOptionalParam($params, "entry_credit", $entry->credit); + $this->addOptionalParam($params, "entry_groupId", $entry->groupId); + $this->addOptionalParam($params, "entry_partnerData", $entry->partnerData); + $this->addOptionalParam($params, "entry_conversionQuality", $entry->conversionQuality); + $this->addOptionalParam($params, "entry_permissions", $entry->permissions); + $this->addOptionalParam($params, "entry_dataContent", $entry->dataContent); + $this->addOptionalParam($params, "entry_desiredVersion", $entry->desiredVersion); + $this->addOptionalParam($params, "entry_url", $entry->url); + $this->addOptionalParam($params, "entry_thumbUrl", $entry->thumbUrl); + $this->addOptionalParam($params, "entry_filename", $entry->filename); + $this->addOptionalParam($params, "entry_realFilename", $entry->realFilename); + $this->addOptionalParam($params, "entry_indexedCustomData1", $entry->indexedCustomData1); + $this->addOptionalParam($params, "entry_thumbOffset", $entry->thumbOffset); + + $result = $this->hit("updatedvdentry", $kalturaSessionUser, $params); + return $result; + } + + public function updateEntriesThumbnails(KalturaSessionUser $kalturaSessionUser, $entryIds, $timeOffset) + { + $params = array(); + $params["entry_ids"] = $entryIds; + $params["time_offset"] = $timeOffset; + + $result = $this->hit("updateentriesthumbnails", $kalturaSessionUser, $params); + return $result; + } + + public function updateEntry(KalturaSessionUser $kalturaSessionUser, $entryId, KalturaEntry $entry) + { + $params = array(); + $params["entry_id"] = $entryId; + $this->addOptionalParam($params, "entry_name", $entry->name); + $this->addOptionalParam($params, "entry_tags", $entry->tags); + $this->addOptionalParam($params, "entry_type", $entry->type); + $this->addOptionalParam($params, "entry_mediaType", $entry->mediaType); + $this->addOptionalParam($params, "entry_source", $entry->source); + $this->addOptionalParam($params, "entry_sourceId", $entry->sourceId); + $this->addOptionalParam($params, "entry_sourceLink", $entry->sourceLink); + $this->addOptionalParam($params, "entry_licenseType", $entry->licenseType); + $this->addOptionalParam($params, "entry_credit", $entry->credit); + $this->addOptionalParam($params, "entry_groupId", $entry->groupId); + $this->addOptionalParam($params, "entry_partnerData", $entry->partnerData); + $this->addOptionalParam($params, "entry_conversionQuality", $entry->conversionQuality); + $this->addOptionalParam($params, "entry_permissions", $entry->permissions); + $this->addOptionalParam($params, "entry_dataContent", $entry->dataContent); + $this->addOptionalParam($params, "entry_desiredVersion", $entry->desiredVersion); + $this->addOptionalParam($params, "entry_url", $entry->url); + $this->addOptionalParam($params, "entry_thumbUrl", $entry->thumbUrl); + $this->addOptionalParam($params, "entry_filename", $entry->filename); + $this->addOptionalParam($params, "entry_realFilename", $entry->realFilename); + $this->addOptionalParam($params, "entry_indexedCustomData1", $entry->indexedCustomData1); + $this->addOptionalParam($params, "entry_thumbOffset", $entry->thumbOffset); + + $result = $this->hit("updateentry", $kalturaSessionUser, $params); + return $result; + } + + public function updateEntryThumbnail(KalturaSessionUser $kalturaSessionUser, $entryId, $sourceEntryId = null, $timeOffset = null) + { + $params = array(); + $params["entry_id"] = $entryId; + $this->addOptionalParam($params, "source_entry_id", $sourceEntryId); + $this->addOptionalParam($params, "time_offset", $timeOffset); + + $result = $this->hit("updateentrythumbnail", $kalturaSessionUser, $params); + return $result; + } + + public function updateEntryThumbnailJpeg(KalturaSessionUser $kalturaSessionUser, $entryId) + { + $params = array(); + $params["entry_id"] = $entryId; + + $result = $this->hit("updateentrythumbnailjpeg", $kalturaSessionUser, $params); + return $result; + } + + public function updateKShow(KalturaSessionUser $kalturaSessionUser, $kshowId, KalturaKShow $kshow, $detailed = null, $allowDuplicateNames = null) + { + $params = array(); + $params["kshow_id"] = $kshowId; + $this->addOptionalParam($params, "kshow_name", $kshow->name); + $this->addOptionalParam($params, "kshow_description", $kshow->description); + $this->addOptionalParam($params, "kshow_tags", $kshow->tags); + $this->addOptionalParam($params, "kshow_indexedCustomData3", $kshow->indexedCustomData3); + $this->addOptionalParam($params, "kshow_groupId", $kshow->groupId); + $this->addOptionalParam($params, "kshow_permissions", $kshow->permissions); + $this->addOptionalParam($params, "kshow_partnerData", $kshow->partnerData); + $this->addOptionalParam($params, "kshow_allowQuickEdit", $kshow->allowQuickEdit); + $this->addOptionalParam($params, "detailed", $detailed); + $this->addOptionalParam($params, "allow_duplicate_names", $allowDuplicateNames); + + $result = $this->hit("updatekshow", $kalturaSessionUser, $params); + return $result; + } + + public function updateKshowOwner(KalturaSessionUser $kalturaSessionUser, $kshowId, $detailed = null) + { + $params = array(); + $params["kshow_id"] = $kshowId; + $this->addOptionalParam($params, "detailed", $detailed); + + $result = $this->hit("updatekshowowner", $kalturaSessionUser, $params); + return $result; + } + + public function updateNotification(KalturaSessionUser $kalturaSessionUser, KalturaNotification $notification) + { + $params = array(); + $this->addOptionalParam($params, "notification_id", $notification->id); + $this->addOptionalParam($params, "notification_status", $notification->status); + $this->addOptionalParam($params, "notification_notificationResult", $notification->notificationResult); + + $result = $this->hit("updatenotification", $kalturaSessionUser, $params); + return $result; + } + + public function updateUser(KalturaSessionUser $kalturaSessionUser, $userId, KalturaUser $user) + { + $params = array(); + $params["user_id"] = $userId; + $this->addOptionalParam($params, "user_screenName", $user->screenName); + $this->addOptionalParam($params, "user_fullName", $user->fullName); + $this->addOptionalParam($params, "user_email", $user->email); + $this->addOptionalParam($params, "user_dateOfBirth", $user->dateOfBirth); + $this->addOptionalParam($params, "user_aboutMe", $user->aboutMe); + $this->addOptionalParam($params, "user_tags", $user->tags); + $this->addOptionalParam($params, "user_gender", $user->gender); + $this->addOptionalParam($params, "user_country", $user->country); + $this->addOptionalParam($params, "user_state", $user->state); + $this->addOptionalParam($params, "user_city", $user->city); + $this->addOptionalParam($params, "user_zip", $user->zip); + $this->addOptionalParam($params, "user_urlList", $user->urlList); + $this->addOptionalParam($params, "user_networkHighschool", $user->networkHighschool); + $this->addOptionalParam($params, "user_networkCollege", $user->networkCollege); + $this->addOptionalParam($params, "user_partnerData", $user->partnerData); + + $result = $this->hit("updateuser", $kalturaSessionUser, $params); + return $result; + } + + public function updateUserId(KalturaSessionUser $kalturaSessionUser, $userId, $newUserId) + { + $params = array(); + $params["user_id"] = $userId; + $params["new_user_id"] = $newUserId; + + $result = $this->hit("updateuserid", $kalturaSessionUser, $params); + return $result; + } + + public function upload(KalturaSessionUser $kalturaSessionUser, $filename) + { + $params = array(); + $params["filename"] = $filename; + + $result = $this->hit("upload", $kalturaSessionUser, $params); + return $result; + } + + public function uploadJpeg(KalturaSessionUser $kalturaSessionUser, $filename, $hash) + { + $params = array(); + $params["filename"] = $filename; + $params["hash"] = $hash; + + $result = $this->hit("uploadjpeg", $kalturaSessionUser, $params); + return $result; + } + + public function viewWidget(KalturaSessionUser $kalturaSessionUser, $entryId = null, $kshowId = null, $widgetId = null, $host = null) + { + $params = array(); + $this->addOptionalParam($params, "entry_id", $entryId); + $this->addOptionalParam($params, "kshow_id", $kshowId); + $this->addOptionalParam($params, "widget_id", $widgetId); + $this->addOptionalParam($params, "host", $host); + + $result = $this->hit("viewwidget", $kalturaSessionUser, $params); + return $result; + } + +} +?> diff --git a/KalturaRecord/deliver/kaltura_client_base.php b/KalturaRecord/deliver/kaltura_client_base.php new file mode 100644 index 0000000..41217fd --- /dev/null +++ b/KalturaRecord/deliver/kaltura_client_base.php @@ -0,0 +1,230 @@ +. +*/ + +class KalturaClientBase +{ + const KALTURA_API_VERSION = "0.7"; + const KALTURA_SERVICE_FORMAT_JSON = 1; + const KALTURA_SERVICE_FORMAT_XML = 2; + const KALTURA_SERVICE_FORMAT_PHP = 3; + + /** + * @var KalturaConfiguration + */ + private $config; + + /** + * @var string + */ + private $ks; + + /** + * @var boolean + */ + private $shouldLog = false; + + /** + * Kaltura client constuctor, expecting configuration object + * + * @param KalturaConfiguration $config + */ + public function __construct(KalturaConfiguration $config) + { + $this->config = $config; + + $logger = $this->config->getLogger(); + if ($logger instanceof IKalturaLogger) + { + $this->shouldLog = true; + } + } + + public function hit($method, KalturaSessionUser $session_user, $params) + { + $start_time = microtime(true); + + $this->log("service url: [" . $this->config->serviceUrl . "]"); + $this->log("trying to call method: [" . $method . "] for user id: [" . $session_user->userId . "] using session: [" .$this->ks . "]"); + + // append the basic params + $params["kaltura_api_version"] = self::KALTURA_API_VERSION; + $params["partner_id"] = $this->config->partnerId; + $params["subp_id"] = $this->config->subPartnerId; + $params["format"] = $this->config->format; + $params["uid"] = $session_user->userId; + $this->addOptionalParam($params, "user_name", $session_user->screenName); + $this->addOptionalParam($params, "ks", $this->ks); + + $url = $this->config->serviceUrl . "/index.php/partnerservices2/" . $method; + $this->log("full reqeust url: [" . $url . "]"); + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_POSTFIELDS, $params); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_USERAGENT, ""); + curl_setopt($ch, CURLOPT_TIMEOUT, 10); + + $signature = $this->signature($params); + $params["kalsig"] = $signature; + + $curl_result = curl_exec($ch); + + $curl_error = curl_error($ch); + + if ($curl_error) + { + // TODO: add error code? + $result["error"] = array($curl_error); + } + else + { + $this->log("result (serialized): " . $curl_result); + + if ($this->config->format == self::KALTURA_SERVICE_FORMAT_PHP) + { + $result = @unserialize($curl_result); + + if (!$result) { + $result["result"] = null; + // TODO: add error code? + $result["error"] = array("failed to serialize server result"); + } + $dump = print_r($result, true); + $this->log("result (object dump): " . $dump); + } + else + { + throw new Exception("unsupported format"); + } + } + + $end_time = microtime (true); + + $this->log("execution time for method [" . $method . "]: [" . ($end_time - $start_time) . "]"); + + return $result; + } + + public function start(KalturaSessionUser $session_user, $secret, $admin = null, $privileges = null, $expiry = 86400) + { + $result = $this->startsession($session_user, $secret, $admin, $privileges, $expiry); + + $this->ks = @$result["result"]["ks"]; + return $result; + } + + private function signature($params) + { + ksort($params); + $str = ""; + foreach ($params as $k => $v) + { + $str .= $k.$v; + } + return md5($str); + } + + public function getKs() + { + return $this->ks; + } + + public function setKs($ks) + { + $this->ks = $ks; + } + + protected function addOptionalParam(&$params, $paramName, $paramValue) + { + if ($paramValue !== null) + { + $params[$paramName] = $paramValue; + } + } + + protected function log($msg) + { + if ($this->shouldLog) + $this->config->getLogger()->log($msg); + } +} + +class KalturaSessionUser +{ + var $userId; + var $screenName; +} + +class KalturaConfiguration +{ + private $logger; + + public $serviceUrl = "http://www.kaltura.com"; + public $format = KalturaClient::KALTURA_SERVICE_FORMAT_PHP; + public $partnerId = null; + public $subPartnerId = null; + + /** + * Constructs new kaltura configuration object, expecting partner id & sub partner id + * + * @param int $partnerId + * @param int $subPartnerId + */ + public function __construct($partnerId, $subPartnerId) + { + $this->partnerId = $partnerId; + $this->subPartnerId = $subPartnerId; + } + + /** + * Set logger to get kaltura client debug logs + * + * @param IKalturaLogger $log + */ + public function setLogger(IKalturaLogger $log) + { + $this->logger = $log; + } + + /** + * Gets the logger (Internal client use) + * + * @return unknown + */ + public function getLogger() + { + return $this->logger; + } +} + +/** + * Implement to get kaltura client logs + * + */ +interface IKalturaLogger +{ + function log($msg); +} + + +?> \ No newline at end of file diff --git a/KalturaRecord/deliver/krecord.php b/KalturaRecord/deliver/krecord.php new file mode 100644 index 0000000..fdf1386 --- /dev/null +++ b/KalturaRecord/deliver/krecord.php @@ -0,0 +1,330 @@ + + + serviceUrl = $host; + $client = new KalturaClient($config); + + $user = new KalturaSessionUser(); + $user->userId = $uid; + $user->screenName = $uname; + + $result = $client->startSession($user, $secret, false, "edit:*"); + $ks = @$result["result"]["ks"]; + + ?> + KRecord - Kaltura Chromeless Recorder - JS Example + + + + + + +
+ This is where the KRecord will be embedded. +
+ +
+
+
+ Camera Quality + + + + + + + + + + + +
+
+
+ Add entry parameters + +
+

Current Status

+

+

Status Log

+
+
+ + + Show debug info: + + + + + \ No newline at end of file diff --git a/KalturaRecord/deliver/locale.xml b/KalturaRecord/deliver/locale.xml new file mode 100644 index 0000000..46fae7c --- /dev/null +++ b/KalturaRecord/deliver/locale.xml @@ -0,0 +1,69 @@ + + + + Button.StopRecord + Click anywhere to stop recording + + + + Button.StartRecord + Click anywhere to start recording + + + + Button.Save + Save + + + + Button.Yes + Yes + + + + Button.No + No + + + + Dialog.Overwrite + Record again without saving? + + + + Dialog.Connecting + Connecting... + + + + Dialog.ConnectionError + Connection error. Please try again later + + + + + Error.micDenied + Mic Denied + + + Error.CameraError + Camera Error + + + Error.MichrophoneError + Michrophone Error + + + Error.ConnectionError + Connection Error + + + Error.ConnectionClosed + Connection Closed + + + Error.cameraDenied + Camera Denied + + + \ No newline at end of file diff --git a/KalturaRecord/deliver/playerProductInstall.swf b/KalturaRecord/deliver/playerProductInstall.swf new file mode 100644 index 0000000..bdc3437 Binary files /dev/null and b/KalturaRecord/deliver/playerProductInstall.swf differ diff --git a/KalturaRecord/deliver/skin.fla b/KalturaRecord/deliver/skin.fla new file mode 100644 index 0000000..e8d3510 Binary files /dev/null and b/KalturaRecord/deliver/skin.fla differ diff --git a/KalturaRecord/deliver/skin.swf b/KalturaRecord/deliver/skin.swf new file mode 100644 index 0000000..010278a Binary files /dev/null and b/KalturaRecord/deliver/skin.swf differ diff --git a/KalturaRecord/demos/testing/AC_OETags.js b/KalturaRecord/demos/testing/AC_OETags.js new file mode 100644 index 0000000..6366467 --- /dev/null +++ b/KalturaRecord/demos/testing/AC_OETags.js @@ -0,0 +1,292 @@ +// Flash Player Version Detection - Rev 1.6 +// Detect Client Browser type +// Copyright(c) 2005-2006 Adobe Macromedia Software, LLC. All rights reserved. +var isIE = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false; +var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false; +var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false; + +function ControlVersion() +{ + var version; + var axo; + var e; + + // NOTE : new ActiveXObject(strFoo) throws an exception if strFoo isn't in the registry + + try { + // version will be set for 7.X or greater players + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7"); + version = axo.GetVariable("$version"); + } catch (e) { + } + + if (!version) + { + try { + // version will be set for 6.X players only + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"); + + // installed player is some revision of 6.0 + // GetVariable("$version") crashes for versions 6.0.22 through 6.0.29, + // so we have to be careful. + + // default to the first public version + version = "WIN 6,0,21,0"; + + // throws if AllowScripAccess does not exist (introduced in 6.0r47) + axo.AllowScriptAccess = "always"; + + // safe to call for 6.0r47 or greater + version = axo.GetVariable("$version"); + + } catch (e) { + } + } + + if (!version) + { + try { + // version will be set for 4.X or 5.X player + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3"); + version = axo.GetVariable("$version"); + } catch (e) { + } + } + + if (!version) + { + try { + // version will be set for 3.X player + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3"); + version = "WIN 3,0,18,0"; + } catch (e) { + } + } + + if (!version) + { + try { + // version will be set for 2.X player + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); + version = "WIN 2,0,0,11"; + } catch (e) { + version = -1; + } + } + + return version; +} + +// JavaScript helper required to detect Flash Player PlugIn version information +function GetSwfVer(){ + // NS/Opera version >= 3 check for Flash plugin in plugin array + var flashVer = -1; + + if (navigator.plugins != null && navigator.plugins.length > 0) { + if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) { + var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : ""; + var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description; + var descArray = flashDescription.split(" "); + var tempArrayMajor = descArray[2].split("."); + var versionMajor = tempArrayMajor[0]; + var versionMinor = tempArrayMajor[1]; + var versionRevision = descArray[3]; + if (versionRevision == "") { + versionRevision = descArray[4]; + } + if (versionRevision[0] == "d") { + versionRevision = versionRevision.substring(1); + } else if (versionRevision[0] == "r") { + versionRevision = versionRevision.substring(1); + if (versionRevision.indexOf("d") > 0) { + versionRevision = versionRevision.substring(0, versionRevision.indexOf("d")); + } + } else if (versionRevision[0] == "b") { + versionRevision = versionRevision.substring(1); + } + var flashVer = versionMajor + "." + versionMinor + "." + versionRevision; + } + } + // MSN/WebTV 2.6 supports Flash 4 + else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4; + // WebTV 2.5 supports Flash 3 + else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3; + // older WebTV supports Flash 2 + else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2; + else if ( isIE && isWin && !isOpera ) { + flashVer = ControlVersion(); + } + return flashVer; +} + +// When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available +function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision) +{ + versionStr = GetSwfVer(); + if (versionStr == -1 ) { + return false; + } else if (versionStr != 0) { + if(isIE && isWin && !isOpera) { + // Given "WIN 2,0,0,11" + tempArray = versionStr.split(" "); // ["WIN", "2,0,0,11"] + tempString = tempArray[1]; // "2,0,0,11" + versionArray = tempString.split(","); // ['2', '0', '0', '11'] + } else { + versionArray = versionStr.split("."); + } + var versionMajor = versionArray[0]; + var versionMinor = versionArray[1]; + var versionRevision = versionArray[2]; + + // is the major.revision >= requested major.revision AND the minor version >= requested minor + if (versionMajor > parseFloat(reqMajorVer)) { + return true; + } else if (versionMajor == parseFloat(reqMajorVer)) { + if (versionMinor > parseFloat(reqMinorVer)) + return true; + else if (versionMinor == parseFloat(reqMinorVer)) { + if (versionRevision >= parseFloat(reqRevision)) + return true; + } + } + return false; + } +} + +function AC_AddExtension(src, ext) +{ + var qIndex = src.indexOf('?'); + if ( qIndex != -1) + { + // Add the extention (if needed) before the query params + var path = src.substring(0, qIndex); + if (path.length >= ext.length && path.lastIndexOf(ext) == (path.length - ext.length)) + return src; + else + return src.replace(/\?/, ext+'?'); + } + else + { + // Add the extension (if needed) to the end of the URL + if (src.length >= ext.length && src.lastIndexOf(ext) == (src.length - ext.length)) + return src; // Already have extension + else + return src + ext; + } +} + +function AC_Generateobj(objAttrs, params, embedAttrs) +{ + var str = ''; + if (isIE && isWin && !isOpera) + { + str += ' '; + str += ''; + } else { + str += ' + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + diff --git a/KalturaRecord/demos/testing/KRecord.swf b/KalturaRecord/demos/testing/KRecord.swf new file mode 100644 index 0000000..99c7413 Binary files /dev/null and b/KalturaRecord/demos/testing/KRecord.swf differ diff --git a/KalturaRecord/demos/testing/history/history.css b/KalturaRecord/demos/testing/history/history.css new file mode 100644 index 0000000..dbc47c6 --- /dev/null +++ b/KalturaRecord/demos/testing/history/history.css @@ -0,0 +1,6 @@ +/* This CSS stylesheet defines styles used by required elements in a flex application page that supports browser history */ + +#ie_historyFrame { width: 0px; height: 0px; display:none } +#firefox_anchorDiv { width: 0px; height: 0px; display:none } +#safari_formDiv { width: 0px; height: 0px; display:none } +#safari_rememberDiv { width: 0px; height: 0px; display:none } diff --git a/KalturaRecord/demos/testing/history/history.js b/KalturaRecord/demos/testing/history/history.js new file mode 100644 index 0000000..3279a53 --- /dev/null +++ b/KalturaRecord/demos/testing/history/history.js @@ -0,0 +1,662 @@ +BrowserHistoryUtils = { + addEvent: function(elm, evType, fn, useCapture) { + useCapture = useCapture || false; + if (elm.addEventListener) { + elm.addEventListener(evType, fn, useCapture); + return true; + } + else if (elm.attachEvent) { + var r = elm.attachEvent('on' + evType, fn); + return r; + } + else { + elm['on' + evType] = fn; + } + } +} + +BrowserHistory = (function() { + // type of browser + var browser = { + ie: false, + firefox: false, + safari: false, + opera: false, + version: -1 + }; + + // if setDefaultURL has been called, our first clue + // that the SWF is ready and listening + //var swfReady = false; + + // the URL we'll send to the SWF once it is ready + //var pendingURL = ''; + + // Default app state URL to use when no fragment ID present + var defaultHash = ''; + + // Last-known app state URL + var currentHref = document.location.href; + + // Initial URL (used only by IE) + var initialHref = document.location.href; + + // Initial URL (used only by IE) + var initialHash = document.location.hash; + + // History frame source URL prefix (used only by IE) + var historyFrameSourcePrefix = 'history/historyFrame.html?'; + + // History maintenance (used only by Safari) + var currentHistoryLength = -1; + + var historyHash = []; + + var initialState = createState(initialHref, initialHref + '#' + initialHash, initialHash); + + var backStack = []; + var forwardStack = []; + + var currentObjectId = null; + + //UserAgent detection + var useragent = navigator.userAgent.toLowerCase(); + + if (useragent.indexOf("opera") != -1) { + browser.opera = true; + } else if (useragent.indexOf("msie") != -1) { + browser.ie = true; + browser.version = parseFloat(useragent.substring(useragent.indexOf('msie') + 4)); + } else if (useragent.indexOf("safari") != -1) { + browser.safari = true; + browser.version = parseFloat(useragent.substring(useragent.indexOf('safari') + 7)); + } else if (useragent.indexOf("gecko") != -1) { + browser.firefox = true; + } + + if (browser.ie == true && browser.version == 7) { + window["_ie_firstload"] = false; + } + + // Accessor functions for obtaining specific elements of the page. + function getHistoryFrame() + { + return document.getElementById('ie_historyFrame'); + } + + function getAnchorElement() + { + return document.getElementById('firefox_anchorDiv'); + } + + function getFormElement() + { + return document.getElementById('safari_formDiv'); + } + + function getRememberElement() + { + return document.getElementById("safari_remember_field"); + } + + // Get the Flash player object for performing ExternalInterface callbacks. + // Updated for changes to SWFObject2. + function getPlayer(id) { + if (id && document.getElementById(id)) { + var r = document.getElementById(id); + if (typeof r.SetVariable != "undefined") { + return r; + } + else { + var o = r.getElementsByTagName("object"); + var e = r.getElementsByTagName("embed"); + if (o.length > 0 && typeof o[0].SetVariable != "undefined") { + return o[0]; + } + else if (e.length > 0 && typeof e[0].SetVariable != "undefined") { + return e[0]; + } + } + } + else { + var o = document.getElementsByTagName("object"); + var e = document.getElementsByTagName("embed"); + if (e.length > 0 && typeof e[0].SetVariable != "undefined") { + return e[0]; + } + else if (o.length > 0 && typeof o[0].SetVariable != "undefined") { + return o[0]; + } + else if (o.length > 1 && typeof o[1].SetVariable != "undefined") { + return o[1]; + } + } + return undefined; + } + + function getPlayers() { + var players = []; + if (players.length == 0) { + var tmp = document.getElementsByTagName('object'); + players = tmp; + } + + if (players.length == 0 || players[0].object == null) { + var tmp = document.getElementsByTagName('embed'); + players = tmp; + } + return players; + } + + function getIframeHash() { + var doc = getHistoryFrame().contentWindow.document; + var hash = String(doc.location.search); + if (hash.length == 1 && hash.charAt(0) == "?") { + hash = ""; + } + else if (hash.length >= 2 && hash.charAt(0) == "?") { + hash = hash.substring(1); + } + return hash; + } + + /* Get the current location hash excluding the '#' symbol. */ + function getHash() { + // It would be nice if we could use document.location.hash here, + // but it's faulty sometimes. + var idx = document.location.href.indexOf('#'); + return (idx >= 0) ? document.location.href.substr(idx+1) : ''; + } + + /* Get the current location hash excluding the '#' symbol. */ + function setHash(hash) { + // It would be nice if we could use document.location.hash here, + // but it's faulty sometimes. + if (hash == '') hash = '#' + document.location.hash = hash; + } + + function createState(baseUrl, newUrl, flexAppUrl) { + return { 'baseUrl': baseUrl, 'newUrl': newUrl, 'flexAppUrl': flexAppUrl, 'title': null }; + } + + /* Add a history entry to the browser. + * baseUrl: the portion of the location prior to the '#' + * newUrl: the entire new URL, including '#' and following fragment + * flexAppUrl: the portion of the location following the '#' only + */ + function addHistoryEntry(baseUrl, newUrl, flexAppUrl) { + + //delete all the history entries + forwardStack = []; + + if (browser.ie) { + //Check to see if we are being asked to do a navigate for the first + //history entry, and if so ignore, because it's coming from the creation + //of the history iframe + if (flexAppUrl == defaultHash && document.location.href == initialHref && window['_ie_firstload']) { + currentHref = initialHref; + return; + } + if ((!flexAppUrl || flexAppUrl == defaultHash) && window['_ie_firstload']) { + newUrl = baseUrl + '#' + defaultHash; + flexAppUrl = defaultHash; + } else { + // for IE, tell the history frame to go somewhere without a '#' + // in order to get this entry into the browser history. + getHistoryFrame().src = historyFrameSourcePrefix + flexAppUrl; + } + setHash(flexAppUrl); + } else { + + //ADR + if (backStack.length == 0 && initialState.flexAppUrl == flexAppUrl) { + initialState = createState(baseUrl, newUrl, flexAppUrl); + } else if(backStack.length > 0 && backStack[backStack.length - 1].flexAppUrl == flexAppUrl) { + backStack[backStack.length - 1] = createState(baseUrl, newUrl, flexAppUrl); + } + + if (browser.safari) { + // for Safari, submit a form whose action points to the desired URL + if (browser.version <= 419.3) { + var file = window.location.pathname.toString(); + file = file.substring(file.lastIndexOf("/")+1); + getFormElement().innerHTML = '
'; + //get the current elements and add them to the form + var qs = window.location.search.substring(1); + var qs_arr = qs.split("&"); + for (var i = 0; i < qs_arr.length; i++) { + var tmp = qs_arr[i].split("="); + var elem = document.createElement("input"); + elem.type = "hidden"; + elem.name = tmp[0]; + elem.value = tmp[1]; + document.forms.historyForm.appendChild(elem); + } + document.forms.historyForm.submit(); + } else { + top.location.hash = flexAppUrl; + } + // We also have to maintain the history by hand for Safari + historyHash[history.length] = flexAppUrl; + _storeStates(); + } else { + // Otherwise, write an anchor into the page and tell the browser to go there + addAnchor(flexAppUrl); + setHash(flexAppUrl); + } + } + backStack.push(createState(baseUrl, newUrl, flexAppUrl)); + } + + function _storeStates() { + if (browser.safari) { + getRememberElement().value = historyHash.join(","); + } + } + + function handleBackButton() { + //The "current" page is always at the top of the history stack. + var current = backStack.pop(); + if (!current) { return; } + var last = backStack[backStack.length - 1]; + if (!last && backStack.length == 0){ + last = initialState; + } + forwardStack.push(current); + } + + function handleForwardButton() { + //summary: private method. Do not call this directly. + + var last = forwardStack.pop(); + if (!last) { return; } + backStack.push(last); + } + + function handleArbitraryUrl() { + //delete all the history entries + forwardStack = []; + } + + /* Called periodically to poll to see if we need to detect navigation that has occurred */ + function checkForUrlChange() { + + if (browser.ie) { + if (currentHref != document.location.href && currentHref + '#' != document.location.href) { + //This occurs when the user has navigated to a specific URL + //within the app, and didn't use browser back/forward + //IE seems to have a bug where it stops updating the URL it + //shows the end-user at this point, but programatically it + //appears to be correct. Do a full app reload to get around + //this issue. + if (browser.version < 7) { + currentHref = document.location.href; + document.location.reload(); + } else { + if (getHash() != getIframeHash()) { + // this.iframe.src = this.blankURL + hash; + var sourceToSet = historyFrameSourcePrefix + getHash(); + getHistoryFrame().src = sourceToSet; + } + } + } + } + + if (browser.safari) { + // For Safari, we have to check to see if history.length changed. + if (currentHistoryLength >= 0 && history.length != currentHistoryLength) { + //alert("did change: " + history.length + ", " + historyHash.length + "|" + historyHash[history.length] + "|>" + historyHash.join("|")); + // If it did change, then we have to look the old state up + // in our hand-maintained array since document.location.hash + // won't have changed, then call back into BrowserManager. + currentHistoryLength = history.length; + var flexAppUrl = historyHash[currentHistoryLength]; + if (flexAppUrl == '') { + //flexAppUrl = defaultHash; + } + //ADR: to fix multiple + if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) { + var pl = getPlayers(); + for (var i = 0; i < pl.length; i++) { + pl[i].browserURLChange(flexAppUrl); + } + } else { + getPlayer().browserURLChange(flexAppUrl); + } + _storeStates(); + } + } + if (browser.firefox) { + if (currentHref != document.location.href) { + var bsl = backStack.length; + + var urlActions = { + back: false, + forward: false, + set: false + } + + if ((window.location.hash == initialHash || window.location.href == initialHref) && (bsl == 1)) { + urlActions.back = true; + // FIXME: could this ever be a forward button? + // we can't clear it because we still need to check for forwards. Ugg. + // clearInterval(this.locationTimer); + handleBackButton(); + } + + // first check to see if we could have gone forward. We always halt on + // a no-hash item. + if (forwardStack.length > 0) { + if (forwardStack[forwardStack.length-1].flexAppUrl == getHash()) { + urlActions.forward = true; + handleForwardButton(); + } + } + + // ok, that didn't work, try someplace back in the history stack + if ((bsl >= 2) && (backStack[bsl - 2])) { + if (backStack[bsl - 2].flexAppUrl == getHash()) { + urlActions.back = true; + handleBackButton(); + } + } + + if (!urlActions.back && !urlActions.forward) { + var foundInStacks = { + back: -1, + forward: -1 + } + + for (var i = 0; i < backStack.length; i++) { + if (backStack[i].flexAppUrl == getHash() && i != (bsl - 2)) { + arbitraryUrl = true; + foundInStacks.back = i; + } + } + for (var i = 0; i < forwardStack.length; i++) { + if (forwardStack[i].flexAppUrl == getHash() && i != (bsl - 2)) { + arbitraryUrl = true; + foundInStacks.forward = i; + } + } + handleArbitraryUrl(); + } + + // Firefox changed; do a callback into BrowserManager to tell it. + currentHref = document.location.href; + var flexAppUrl = getHash(); + if (flexAppUrl == '') { + //flexAppUrl = defaultHash; + } + //ADR: to fix multiple + if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) { + var pl = getPlayers(); + for (var i = 0; i < pl.length; i++) { + pl[i].browserURLChange(flexAppUrl); + } + } else { + getPlayer().browserURLChange(flexAppUrl); + } + } + } + //setTimeout(checkForUrlChange, 50); + } + + /* Write an anchor into the page to legitimize it as a URL for Firefox et al. */ + function addAnchor(flexAppUrl) + { + if (document.getElementsByName(flexAppUrl).length == 0) { + getAnchorElement().innerHTML += "" + flexAppUrl + ""; + } + } + + var _initialize = function () { + if (browser.ie) + { + var scripts = document.getElementsByTagName('script'); + for (var i = 0, s; s = scripts[i]; i++) { + if (s.src.indexOf("history.js") > -1) { + var iframe_location = (new String(s.src)).replace("history.js", "historyFrame.html"); + } + } + historyFrameSourcePrefix = iframe_location + "?"; + var src = historyFrameSourcePrefix; + + var iframe = document.createElement("iframe"); + iframe.id = 'ie_historyFrame'; + iframe.name = 'ie_historyFrame'; + //iframe.src = historyFrameSourcePrefix; + try { + document.body.appendChild(iframe); + } catch(e) { + setTimeout(function() { + document.body.appendChild(iframe); + }, 0); + } + } + + if (browser.safari) + { + var rememberDiv = document.createElement("div"); + rememberDiv.id = 'safari_rememberDiv'; + document.body.appendChild(rememberDiv); + rememberDiv.innerHTML = ''; + + var formDiv = document.createElement("div"); + formDiv.id = 'safari_formDiv'; + document.body.appendChild(formDiv); + + var reloader_content = document.createElement('div'); + reloader_content.id = 'safarireloader'; + var scripts = document.getElementsByTagName('script'); + for (var i = 0, s; s = scripts[i]; i++) { + if (s.src.indexOf("history.js") > -1) { + html = (new String(s.src)).replace(".js", ".html"); + } + } + reloader_content.innerHTML = ''; + document.body.appendChild(reloader_content); + reloader_content.style.position = 'absolute'; + reloader_content.style.left = reloader_content.style.top = '-9999px'; + iframe = reloader_content.getElementsByTagName('iframe')[0]; + + if (document.getElementById("safari_remember_field").value != "" ) { + historyHash = document.getElementById("safari_remember_field").value.split(","); + } + + } + + if (browser.firefox) + { + var anchorDiv = document.createElement("div"); + anchorDiv.id = 'firefox_anchorDiv'; + document.body.appendChild(anchorDiv); + } + + //setTimeout(checkForUrlChange, 50); + } + + return { + historyHash: historyHash, + backStack: function() { return backStack; }, + forwardStack: function() { return forwardStack }, + getPlayer: getPlayer, + initialize: function(src) { + _initialize(src); + }, + setURL: function(url) { + document.location.href = url; + }, + getURL: function() { + return document.location.href; + }, + getTitle: function() { + return document.title; + }, + setTitle: function(title) { + try { + backStack[backStack.length - 1].title = title; + } catch(e) { } + //if on safari, set the title to be the empty string. + if (browser.safari) { + if (title == "") { + try { + var tmp = window.location.href.toString(); + title = tmp.substring((tmp.lastIndexOf("/")+1), tmp.lastIndexOf("#")); + } catch(e) { + title = ""; + } + } + } + document.title = title; + }, + setDefaultURL: function(def) + { + defaultHash = def; + def = getHash(); + //trailing ? is important else an extra frame gets added to the history + //when navigating back to the first page. Alternatively could check + //in history frame navigation to compare # and ?. + if (browser.ie) + { + window['_ie_firstload'] = true; + var sourceToSet = historyFrameSourcePrefix + def; + var func = function() { + getHistoryFrame().src = sourceToSet; + window.location.replace("#" + def); + setInterval(checkForUrlChange, 50); + } + try { + func(); + } catch(e) { + window.setTimeout(function() { func(); }, 0); + } + } + + if (browser.safari) + { + currentHistoryLength = history.length; + if (historyHash.length == 0) { + historyHash[currentHistoryLength] = def; + var newloc = "#" + def; + window.location.replace(newloc); + } else { + //alert(historyHash[historyHash.length-1]); + } + //setHash(def); + setInterval(checkForUrlChange, 50); + } + + + if (browser.firefox || browser.opera) + { + var reg = new RegExp("#" + def + "$"); + if (window.location.toString().match(reg)) { + } else { + var newloc ="#" + def; + window.location.replace(newloc); + } + setInterval(checkForUrlChange, 50); + //setHash(def); + } + + }, + + /* Set the current browser URL; called from inside BrowserManager to propagate + * the application state out to the container. + */ + setBrowserURL: function(flexAppUrl, objectId) { + if (browser.ie && typeof objectId != "undefined") { + currentObjectId = objectId; + } + //fromIframe = fromIframe || false; + //fromFlex = fromFlex || false; + //alert("setBrowserURL: " + flexAppUrl); + //flexAppUrl = (flexAppUrl == "") ? defaultHash : flexAppUrl ; + + var pos = document.location.href.indexOf('#'); + var baseUrl = pos != -1 ? document.location.href.substr(0, pos) : document.location.href; + var newUrl = baseUrl + '#' + flexAppUrl; + + if (document.location.href != newUrl && document.location.href + '#' != newUrl) { + currentHref = newUrl; + addHistoryEntry(baseUrl, newUrl, flexAppUrl); + currentHistoryLength = history.length; + } + + return false; + }, + + browserURLChange: function(flexAppUrl) { + var objectId = null; + if (browser.ie && currentObjectId != null) { + objectId = currentObjectId; + } + pendingURL = ''; + + if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) { + var pl = getPlayers(); + for (var i = 0; i < pl.length; i++) { + try { + pl[i].browserURLChange(flexAppUrl); + } catch(e) { } + } + } else { + try { + getPlayer(objectId).browserURLChange(flexAppUrl); + } catch(e) { } + } + + currentObjectId = null; + } + + } + +})(); + +// Initialization + +// Automated unit testing and other diagnostics + +function setURL(url) +{ + document.location.href = url; +} + +function backButton() +{ + history.back(); +} + +function forwardButton() +{ + history.forward(); +} + +function goForwardOrBackInHistory(step) +{ + history.go(step); +} + +//BrowserHistoryUtils.addEvent(window, "load", function() { BrowserHistory.initialize(); }); +(function(i) { + var u =navigator.userAgent;var e=/*@cc_on!@*/false; + var st = setTimeout; + if(/webkit/i.test(u)){ + st(function(){ + var dr=document.readyState; + if(dr=="loaded"||dr=="complete"){i()} + else{st(arguments.callee,10);}},10); + } else if((/mozilla/i.test(u)&&!/(compati)/.test(u)) || (/opera/i.test(u))){ + document.addEventListener("DOMContentLoaded",i,false); + } else if(e){ + (function(){ + var t=document.createElement('doc:rdy'); + try{t.doScroll('left'); + i();t=null; + }catch(e){st(arguments.callee,0);}})(); + } else{ + window.onload=i; + } +})( function() {BrowserHistory.initialize();} ); diff --git a/KalturaRecord/demos/testing/history/historyFrame.html b/KalturaRecord/demos/testing/history/historyFrame.html new file mode 100644 index 0000000..07e3806 --- /dev/null +++ b/KalturaRecord/demos/testing/history/historyFrame.html @@ -0,0 +1,29 @@ + + + + + + + + Hidden frame for Browser History support. + + diff --git a/KalturaRecord/demos/testing/playerProductInstall.swf b/KalturaRecord/demos/testing/playerProductInstall.swf new file mode 100644 index 0000000..bdc3437 Binary files /dev/null and b/KalturaRecord/demos/testing/playerProductInstall.swf differ diff --git a/KalturaRecord/demos/testing/skin.swf b/KalturaRecord/demos/testing/skin.swf new file mode 100644 index 0000000..f70e45e Binary files /dev/null and b/KalturaRecord/demos/testing/skin.swf differ diff --git a/KalturaRecord/html-template/AC_OETags.js b/KalturaRecord/html-template/AC_OETags.js new file mode 100644 index 0000000..6366467 --- /dev/null +++ b/KalturaRecord/html-template/AC_OETags.js @@ -0,0 +1,292 @@ +// Flash Player Version Detection - Rev 1.6 +// Detect Client Browser type +// Copyright(c) 2005-2006 Adobe Macromedia Software, LLC. All rights reserved. +var isIE = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false; +var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false; +var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false; + +function ControlVersion() +{ + var version; + var axo; + var e; + + // NOTE : new ActiveXObject(strFoo) throws an exception if strFoo isn't in the registry + + try { + // version will be set for 7.X or greater players + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7"); + version = axo.GetVariable("$version"); + } catch (e) { + } + + if (!version) + { + try { + // version will be set for 6.X players only + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"); + + // installed player is some revision of 6.0 + // GetVariable("$version") crashes for versions 6.0.22 through 6.0.29, + // so we have to be careful. + + // default to the first public version + version = "WIN 6,0,21,0"; + + // throws if AllowScripAccess does not exist (introduced in 6.0r47) + axo.AllowScriptAccess = "always"; + + // safe to call for 6.0r47 or greater + version = axo.GetVariable("$version"); + + } catch (e) { + } + } + + if (!version) + { + try { + // version will be set for 4.X or 5.X player + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3"); + version = axo.GetVariable("$version"); + } catch (e) { + } + } + + if (!version) + { + try { + // version will be set for 3.X player + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3"); + version = "WIN 3,0,18,0"; + } catch (e) { + } + } + + if (!version) + { + try { + // version will be set for 2.X player + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); + version = "WIN 2,0,0,11"; + } catch (e) { + version = -1; + } + } + + return version; +} + +// JavaScript helper required to detect Flash Player PlugIn version information +function GetSwfVer(){ + // NS/Opera version >= 3 check for Flash plugin in plugin array + var flashVer = -1; + + if (navigator.plugins != null && navigator.plugins.length > 0) { + if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) { + var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : ""; + var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description; + var descArray = flashDescription.split(" "); + var tempArrayMajor = descArray[2].split("."); + var versionMajor = tempArrayMajor[0]; + var versionMinor = tempArrayMajor[1]; + var versionRevision = descArray[3]; + if (versionRevision == "") { + versionRevision = descArray[4]; + } + if (versionRevision[0] == "d") { + versionRevision = versionRevision.substring(1); + } else if (versionRevision[0] == "r") { + versionRevision = versionRevision.substring(1); + if (versionRevision.indexOf("d") > 0) { + versionRevision = versionRevision.substring(0, versionRevision.indexOf("d")); + } + } else if (versionRevision[0] == "b") { + versionRevision = versionRevision.substring(1); + } + var flashVer = versionMajor + "." + versionMinor + "." + versionRevision; + } + } + // MSN/WebTV 2.6 supports Flash 4 + else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4; + // WebTV 2.5 supports Flash 3 + else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3; + // older WebTV supports Flash 2 + else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2; + else if ( isIE && isWin && !isOpera ) { + flashVer = ControlVersion(); + } + return flashVer; +} + +// When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available +function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision) +{ + versionStr = GetSwfVer(); + if (versionStr == -1 ) { + return false; + } else if (versionStr != 0) { + if(isIE && isWin && !isOpera) { + // Given "WIN 2,0,0,11" + tempArray = versionStr.split(" "); // ["WIN", "2,0,0,11"] + tempString = tempArray[1]; // "2,0,0,11" + versionArray = tempString.split(","); // ['2', '0', '0', '11'] + } else { + versionArray = versionStr.split("."); + } + var versionMajor = versionArray[0]; + var versionMinor = versionArray[1]; + var versionRevision = versionArray[2]; + + // is the major.revision >= requested major.revision AND the minor version >= requested minor + if (versionMajor > parseFloat(reqMajorVer)) { + return true; + } else if (versionMajor == parseFloat(reqMajorVer)) { + if (versionMinor > parseFloat(reqMinorVer)) + return true; + else if (versionMinor == parseFloat(reqMinorVer)) { + if (versionRevision >= parseFloat(reqRevision)) + return true; + } + } + return false; + } +} + +function AC_AddExtension(src, ext) +{ + var qIndex = src.indexOf('?'); + if ( qIndex != -1) + { + // Add the extention (if needed) before the query params + var path = src.substring(0, qIndex); + if (path.length >= ext.length && path.lastIndexOf(ext) == (path.length - ext.length)) + return src; + else + return src.replace(/\?/, ext+'?'); + } + else + { + // Add the extension (if needed) to the end of the URL + if (src.length >= ext.length && src.lastIndexOf(ext) == (src.length - ext.length)) + return src; // Already have extension + else + return src + ext; + } +} + +function AC_Generateobj(objAttrs, params, embedAttrs) +{ + var str = ''; + if (isIE && isWin && !isOpera) + { + str += ' '; + str += ''; + } else { + str += ' 0 && typeof o[0].SetVariable != "undefined") { + return o[0]; + } + else if (e.length > 0 && typeof e[0].SetVariable != "undefined") { + return e[0]; + } + } + } + else { + var o = document.getElementsByTagName("object"); + var e = document.getElementsByTagName("embed"); + if (e.length > 0 && typeof e[0].SetVariable != "undefined") { + return e[0]; + } + else if (o.length > 0 && typeof o[0].SetVariable != "undefined") { + return o[0]; + } + else if (o.length > 1 && typeof o[1].SetVariable != "undefined") { + return o[1]; + } + } + return undefined; + } + + function getPlayers() { + var players = []; + if (players.length == 0) { + var tmp = document.getElementsByTagName('object'); + players = tmp; + } + + if (players.length == 0 || players[0].object == null) { + var tmp = document.getElementsByTagName('embed'); + players = tmp; + } + return players; + } + + function getIframeHash() { + var doc = getHistoryFrame().contentWindow.document; + var hash = String(doc.location.search); + if (hash.length == 1 && hash.charAt(0) == "?") { + hash = ""; + } + else if (hash.length >= 2 && hash.charAt(0) == "?") { + hash = hash.substring(1); + } + return hash; + } + + /* Get the current location hash excluding the '#' symbol. */ + function getHash() { + // It would be nice if we could use document.location.hash here, + // but it's faulty sometimes. + var idx = document.location.href.indexOf('#'); + return (idx >= 0) ? document.location.href.substr(idx+1) : ''; + } + + /* Get the current location hash excluding the '#' symbol. */ + function setHash(hash) { + // It would be nice if we could use document.location.hash here, + // but it's faulty sometimes. + if (hash == '') hash = '#' + document.location.hash = hash; + } + + function createState(baseUrl, newUrl, flexAppUrl) { + return { 'baseUrl': baseUrl, 'newUrl': newUrl, 'flexAppUrl': flexAppUrl, 'title': null }; + } + + /* Add a history entry to the browser. + * baseUrl: the portion of the location prior to the '#' + * newUrl: the entire new URL, including '#' and following fragment + * flexAppUrl: the portion of the location following the '#' only + */ + function addHistoryEntry(baseUrl, newUrl, flexAppUrl) { + + //delete all the history entries + forwardStack = []; + + if (browser.ie) { + //Check to see if we are being asked to do a navigate for the first + //history entry, and if so ignore, because it's coming from the creation + //of the history iframe + if (flexAppUrl == defaultHash && document.location.href == initialHref && window['_ie_firstload']) { + currentHref = initialHref; + return; + } + if ((!flexAppUrl || flexAppUrl == defaultHash) && window['_ie_firstload']) { + newUrl = baseUrl + '#' + defaultHash; + flexAppUrl = defaultHash; + } else { + // for IE, tell the history frame to go somewhere without a '#' + // in order to get this entry into the browser history. + getHistoryFrame().src = historyFrameSourcePrefix + flexAppUrl; + } + setHash(flexAppUrl); + } else { + + //ADR + if (backStack.length == 0 && initialState.flexAppUrl == flexAppUrl) { + initialState = createState(baseUrl, newUrl, flexAppUrl); + } else if(backStack.length > 0 && backStack[backStack.length - 1].flexAppUrl == flexAppUrl) { + backStack[backStack.length - 1] = createState(baseUrl, newUrl, flexAppUrl); + } + + if (browser.safari) { + // for Safari, submit a form whose action points to the desired URL + if (browser.version <= 419.3) { + var file = window.location.pathname.toString(); + file = file.substring(file.lastIndexOf("/")+1); + getFormElement().innerHTML = '
'; + //get the current elements and add them to the form + var qs = window.location.search.substring(1); + var qs_arr = qs.split("&"); + for (var i = 0; i < qs_arr.length; i++) { + var tmp = qs_arr[i].split("="); + var elem = document.createElement("input"); + elem.type = "hidden"; + elem.name = tmp[0]; + elem.value = tmp[1]; + document.forms.historyForm.appendChild(elem); + } + document.forms.historyForm.submit(); + } else { + top.location.hash = flexAppUrl; + } + // We also have to maintain the history by hand for Safari + historyHash[history.length] = flexAppUrl; + _storeStates(); + } else { + // Otherwise, write an anchor into the page and tell the browser to go there + addAnchor(flexAppUrl); + setHash(flexAppUrl); + } + } + backStack.push(createState(baseUrl, newUrl, flexAppUrl)); + } + + function _storeStates() { + if (browser.safari) { + getRememberElement().value = historyHash.join(","); + } + } + + function handleBackButton() { + //The "current" page is always at the top of the history stack. + var current = backStack.pop(); + if (!current) { return; } + var last = backStack[backStack.length - 1]; + if (!last && backStack.length == 0){ + last = initialState; + } + forwardStack.push(current); + } + + function handleForwardButton() { + //summary: private method. Do not call this directly. + + var last = forwardStack.pop(); + if (!last) { return; } + backStack.push(last); + } + + function handleArbitraryUrl() { + //delete all the history entries + forwardStack = []; + } + + /* Called periodically to poll to see if we need to detect navigation that has occurred */ + function checkForUrlChange() { + + if (browser.ie) { + if (currentHref != document.location.href && currentHref + '#' != document.location.href) { + //This occurs when the user has navigated to a specific URL + //within the app, and didn't use browser back/forward + //IE seems to have a bug where it stops updating the URL it + //shows the end-user at this point, but programatically it + //appears to be correct. Do a full app reload to get around + //this issue. + if (browser.version < 7) { + currentHref = document.location.href; + document.location.reload(); + } else { + if (getHash() != getIframeHash()) { + // this.iframe.src = this.blankURL + hash; + var sourceToSet = historyFrameSourcePrefix + getHash(); + getHistoryFrame().src = sourceToSet; + } + } + } + } + + if (browser.safari) { + // For Safari, we have to check to see if history.length changed. + if (currentHistoryLength >= 0 && history.length != currentHistoryLength) { + //alert("did change: " + history.length + ", " + historyHash.length + "|" + historyHash[history.length] + "|>" + historyHash.join("|")); + // If it did change, then we have to look the old state up + // in our hand-maintained array since document.location.hash + // won't have changed, then call back into BrowserManager. + currentHistoryLength = history.length; + var flexAppUrl = historyHash[currentHistoryLength]; + if (flexAppUrl == '') { + //flexAppUrl = defaultHash; + } + //ADR: to fix multiple + if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) { + var pl = getPlayers(); + for (var i = 0; i < pl.length; i++) { + pl[i].browserURLChange(flexAppUrl); + } + } else { + getPlayer().browserURLChange(flexAppUrl); + } + _storeStates(); + } + } + if (browser.firefox) { + if (currentHref != document.location.href) { + var bsl = backStack.length; + + var urlActions = { + back: false, + forward: false, + set: false + } + + if ((window.location.hash == initialHash || window.location.href == initialHref) && (bsl == 1)) { + urlActions.back = true; + // FIXME: could this ever be a forward button? + // we can't clear it because we still need to check for forwards. Ugg. + // clearInterval(this.locationTimer); + handleBackButton(); + } + + // first check to see if we could have gone forward. We always halt on + // a no-hash item. + if (forwardStack.length > 0) { + if (forwardStack[forwardStack.length-1].flexAppUrl == getHash()) { + urlActions.forward = true; + handleForwardButton(); + } + } + + // ok, that didn't work, try someplace back in the history stack + if ((bsl >= 2) && (backStack[bsl - 2])) { + if (backStack[bsl - 2].flexAppUrl == getHash()) { + urlActions.back = true; + handleBackButton(); + } + } + + if (!urlActions.back && !urlActions.forward) { + var foundInStacks = { + back: -1, + forward: -1 + } + + for (var i = 0; i < backStack.length; i++) { + if (backStack[i].flexAppUrl == getHash() && i != (bsl - 2)) { + arbitraryUrl = true; + foundInStacks.back = i; + } + } + for (var i = 0; i < forwardStack.length; i++) { + if (forwardStack[i].flexAppUrl == getHash() && i != (bsl - 2)) { + arbitraryUrl = true; + foundInStacks.forward = i; + } + } + handleArbitraryUrl(); + } + + // Firefox changed; do a callback into BrowserManager to tell it. + currentHref = document.location.href; + var flexAppUrl = getHash(); + if (flexAppUrl == '') { + //flexAppUrl = defaultHash; + } + //ADR: to fix multiple + if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) { + var pl = getPlayers(); + for (var i = 0; i < pl.length; i++) { + pl[i].browserURLChange(flexAppUrl); + } + } else { + getPlayer().browserURLChange(flexAppUrl); + } + } + } + //setTimeout(checkForUrlChange, 50); + } + + /* Write an anchor into the page to legitimize it as a URL for Firefox et al. */ + function addAnchor(flexAppUrl) + { + if (document.getElementsByName(flexAppUrl).length == 0) { + getAnchorElement().innerHTML += "" + flexAppUrl + ""; + } + } + + var _initialize = function () { + if (browser.ie) + { + var scripts = document.getElementsByTagName('script'); + for (var i = 0, s; s = scripts[i]; i++) { + if (s.src.indexOf("history.js") > -1) { + var iframe_location = (new String(s.src)).replace("history.js", "historyFrame.html"); + } + } + historyFrameSourcePrefix = iframe_location + "?"; + var src = historyFrameSourcePrefix; + + var iframe = document.createElement("iframe"); + iframe.id = 'ie_historyFrame'; + iframe.name = 'ie_historyFrame'; + //iframe.src = historyFrameSourcePrefix; + try { + document.body.appendChild(iframe); + } catch(e) { + setTimeout(function() { + document.body.appendChild(iframe); + }, 0); + } + } + + if (browser.safari) + { + var rememberDiv = document.createElement("div"); + rememberDiv.id = 'safari_rememberDiv'; + document.body.appendChild(rememberDiv); + rememberDiv.innerHTML = ''; + + var formDiv = document.createElement("div"); + formDiv.id = 'safari_formDiv'; + document.body.appendChild(formDiv); + + var reloader_content = document.createElement('div'); + reloader_content.id = 'safarireloader'; + var scripts = document.getElementsByTagName('script'); + for (var i = 0, s; s = scripts[i]; i++) { + if (s.src.indexOf("history.js") > -1) { + html = (new String(s.src)).replace(".js", ".html"); + } + } + reloader_content.innerHTML = ''; + document.body.appendChild(reloader_content); + reloader_content.style.position = 'absolute'; + reloader_content.style.left = reloader_content.style.top = '-9999px'; + iframe = reloader_content.getElementsByTagName('iframe')[0]; + + if (document.getElementById("safari_remember_field").value != "" ) { + historyHash = document.getElementById("safari_remember_field").value.split(","); + } + + } + + if (browser.firefox) + { + var anchorDiv = document.createElement("div"); + anchorDiv.id = 'firefox_anchorDiv'; + document.body.appendChild(anchorDiv); + } + + //setTimeout(checkForUrlChange, 50); + } + + return { + historyHash: historyHash, + backStack: function() { return backStack; }, + forwardStack: function() { return forwardStack }, + getPlayer: getPlayer, + initialize: function(src) { + _initialize(src); + }, + setURL: function(url) { + document.location.href = url; + }, + getURL: function() { + return document.location.href; + }, + getTitle: function() { + return document.title; + }, + setTitle: function(title) { + try { + backStack[backStack.length - 1].title = title; + } catch(e) { } + //if on safari, set the title to be the empty string. + if (browser.safari) { + if (title == "") { + try { + var tmp = window.location.href.toString(); + title = tmp.substring((tmp.lastIndexOf("/")+1), tmp.lastIndexOf("#")); + } catch(e) { + title = ""; + } + } + } + document.title = title; + }, + setDefaultURL: function(def) + { + defaultHash = def; + def = getHash(); + //trailing ? is important else an extra frame gets added to the history + //when navigating back to the first page. Alternatively could check + //in history frame navigation to compare # and ?. + if (browser.ie) + { + window['_ie_firstload'] = true; + var sourceToSet = historyFrameSourcePrefix + def; + var func = function() { + getHistoryFrame().src = sourceToSet; + window.location.replace("#" + def); + setInterval(checkForUrlChange, 50); + } + try { + func(); + } catch(e) { + window.setTimeout(function() { func(); }, 0); + } + } + + if (browser.safari) + { + currentHistoryLength = history.length; + if (historyHash.length == 0) { + historyHash[currentHistoryLength] = def; + var newloc = "#" + def; + window.location.replace(newloc); + } else { + //alert(historyHash[historyHash.length-1]); + } + //setHash(def); + setInterval(checkForUrlChange, 50); + } + + + if (browser.firefox || browser.opera) + { + var reg = new RegExp("#" + def + "$"); + if (window.location.toString().match(reg)) { + } else { + var newloc ="#" + def; + window.location.replace(newloc); + } + setInterval(checkForUrlChange, 50); + //setHash(def); + } + + }, + + /* Set the current browser URL; called from inside BrowserManager to propagate + * the application state out to the container. + */ + setBrowserURL: function(flexAppUrl, objectId) { + if (browser.ie && typeof objectId != "undefined") { + currentObjectId = objectId; + } + //fromIframe = fromIframe || false; + //fromFlex = fromFlex || false; + //alert("setBrowserURL: " + flexAppUrl); + //flexAppUrl = (flexAppUrl == "") ? defaultHash : flexAppUrl ; + + var pos = document.location.href.indexOf('#'); + var baseUrl = pos != -1 ? document.location.href.substr(0, pos) : document.location.href; + var newUrl = baseUrl + '#' + flexAppUrl; + + if (document.location.href != newUrl && document.location.href + '#' != newUrl) { + currentHref = newUrl; + addHistoryEntry(baseUrl, newUrl, flexAppUrl); + currentHistoryLength = history.length; + } + + return false; + }, + + browserURLChange: function(flexAppUrl) { + var objectId = null; + if (browser.ie && currentObjectId != null) { + objectId = currentObjectId; + } + pendingURL = ''; + + if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) { + var pl = getPlayers(); + for (var i = 0; i < pl.length; i++) { + try { + pl[i].browserURLChange(flexAppUrl); + } catch(e) { } + } + } else { + try { + getPlayer(objectId).browserURLChange(flexAppUrl); + } catch(e) { } + } + + currentObjectId = null; + } + + } + +})(); + +// Initialization + +// Automated unit testing and other diagnostics + +function setURL(url) +{ + document.location.href = url; +} + +function backButton() +{ + history.back(); +} + +function forwardButton() +{ + history.forward(); +} + +function goForwardOrBackInHistory(step) +{ + history.go(step); +} + +//BrowserHistoryUtils.addEvent(window, "load", function() { BrowserHistory.initialize(); }); +(function(i) { + var u =navigator.userAgent;var e=/*@cc_on!@*/false; + var st = setTimeout; + if(/webkit/i.test(u)){ + st(function(){ + var dr=document.readyState; + if(dr=="loaded"||dr=="complete"){i()} + else{st(arguments.callee,10);}},10); + } else if((/mozilla/i.test(u)&&!/(compati)/.test(u)) || (/opera/i.test(u))){ + document.addEventListener("DOMContentLoaded",i,false); + } else if(e){ + (function(){ + var t=document.createElement('doc:rdy'); + try{t.doScroll('left'); + i();t=null; + }catch(e){st(arguments.callee,0);}})(); + } else{ + window.onload=i; + } +})( function() {BrowserHistory.initialize();} ); diff --git a/KalturaRecord/html-template/history/historyFrame.html b/KalturaRecord/html-template/history/historyFrame.html new file mode 100644 index 0000000..07e3806 --- /dev/null +++ b/KalturaRecord/html-template/history/historyFrame.html @@ -0,0 +1,29 @@ + + + + + + + + Hidden frame for Browser History support. + + diff --git a/KalturaRecord/html-template/index.template.html b/KalturaRecord/html-template/index.template.html new file mode 100644 index 0000000..e49eacb --- /dev/null +++ b/KalturaRecord/html-template/index.template.html @@ -0,0 +1,223 @@ + + + + + + + + + + + + +${title} + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + diff --git a/KalturaRecord/html-template/playerProductInstall.swf b/KalturaRecord/html-template/playerProductInstall.swf new file mode 100644 index 0000000..bdc3437 Binary files /dev/null and b/KalturaRecord/html-template/playerProductInstall.swf differ diff --git a/KalturaRecord/library/KalturaBase.swc b/KalturaRecord/library/KalturaBase.swc new file mode 100644 index 0000000..eb1f7f7 Binary files /dev/null and b/KalturaRecord/library/KalturaBase.swc differ diff --git a/KalturaRecord/library/KalturaLib.swc b/KalturaRecord/library/KalturaLib.swc new file mode 100644 index 0000000..531a5d0 Binary files /dev/null and b/KalturaRecord/library/KalturaLib.swc differ diff --git a/KalturaRecord/library/KalturaNet.swc b/KalturaRecord/library/KalturaNet.swc new file mode 100644 index 0000000..28dd7ed Binary files /dev/null and b/KalturaRecord/library/KalturaNet.swc differ diff --git a/KalturaRecord/library/Preloader.swf.fla b/KalturaRecord/library/Preloader.swf.fla new file mode 100644 index 0000000..d8e1b47 Binary files /dev/null and b/KalturaRecord/library/Preloader.swf.fla differ diff --git a/KalturaRecord/library/Preloader.swf.swc b/KalturaRecord/library/Preloader.swf.swc new file mode 100644 index 0000000..f96b1cd Binary files /dev/null and b/KalturaRecord/library/Preloader.swf.swc differ diff --git a/KalturaRecord/library/Preloader.swf.swf b/KalturaRecord/library/Preloader.swf.swf new file mode 100644 index 0000000..92ec8a0 Binary files /dev/null and b/KalturaRecord/library/Preloader.swf.swf differ diff --git a/KalturaRecord/library/skin.fla b/KalturaRecord/library/skin.fla new file mode 100644 index 0000000..64a8cd4 Binary files /dev/null and b/KalturaRecord/library/skin.fla differ diff --git a/KalturaRecord/library/skin.swf b/KalturaRecord/library/skin.swf new file mode 100644 index 0000000..c564623 Binary files /dev/null and b/KalturaRecord/library/skin.swf differ diff --git a/KalturaRecord/src/ApplicationLoader.as b/KalturaRecord/src/ApplicationLoader.as new file mode 100644 index 0000000..5e1da48 --- /dev/null +++ b/KalturaRecord/src/ApplicationLoader.as @@ -0,0 +1,63 @@ +package +{ + +import flash.display.DisplayObject; +import flash.display.MovieClip; +import flash.events.Event; +import flash.utils.getDefinitionByName; + + +public class ApplicationLoader extends MovieClip +{ + public var application:Object; + //public var parameters:Object = new Object(); + + public function ApplicationLoader() + { + stop(); + addEventListener(Event.ADDED_TO_STAGE, addedToStage); + } + + private function addedToStage(event:Event):void { + removeEventListener(Event.ADDED_TO_STAGE, addedToStage); + + parent.addEventListener( Event.RESIZE, onResize ); + + Global.PRELOADER = new PreloaderSkin(); + + addChild(Global.PRELOADER); + addEventListener(Event.ENTER_FRAME, onEnterFrame); + + onResize(null); + } + + private function onEnterFrame(evt:Event):void + { + if (framesLoaded == totalFrames){ + onLoadComplete(); + } + } + + private function onResize (evt:Event):void + { + Global.PRELOADER.x = int(parent.width / 2); + Global.PRELOADER.y = int(parent.height / 2); + } + + private function onLoadComplete():void + { + removeEventListener(Event.ENTER_FRAME, onEnterFrame); + parent.removeEventListener(Event.RESIZE, onResize); + nextFrame(); + + var MainApp:Class = Class(getDefinitionByName(currentLabels[1].name)); + application = new MainApp(); + + //TODO: Change to recevice the parameters from outside + ////////////////////////////////////////////////////////// + application.pushParameters = stage.loaderInfo.parameters; + ////////////////////////////////////////////////////////// + addChildAt(application as DisplayObject, 0); + } +} +} \ No newline at end of file diff --git a/KalturaRecord/src/Global.as b/KalturaRecord/src/Global.as new file mode 100644 index 0000000..956d6de --- /dev/null +++ b/KalturaRecord/src/Global.as @@ -0,0 +1,26 @@ +package +{ + +import com.kaltura.KalturaClient; +import com.kaltura.recording.controller.IRecordControl; +import com.kaltura.recording.view.KRecordViewParams; +import com.kaltura.recording.view.Theme; +import com.kaltura.utils.Locale; + + +public class Global +{ + + static public var PRELOADER:PreloaderSkin; + static public var VIEW_PARAMS:KRecordViewParams; + static public var THEME:Theme; + static public var LOCALE:Locale; + static public var RECORD_CONTROL:IRecordControl; + static public var KALTURA_CLIENT:KalturaClient; + static public var DISABLE_GLOBAL_CLICK:Boolean = false; + static public var REMOVE_PLAYER:Boolean = false; + static public var SHOW_PREVIEW_TIMER:Boolean = false; + static public var DETECTION_DELAY:uint; + +} +} \ No newline at end of file diff --git a/KalturaRecord/src/KRecord.as b/KalturaRecord/src/KRecord.as new file mode 100644 index 0000000..1674956 --- /dev/null +++ b/KalturaRecord/src/KRecord.as @@ -0,0 +1,880 @@ +/* + // =================================================================================================== + // _ __ _ _ + // | |/ /__ _| | |_ _ _ _ _ __ _ + // | ' . + // + // @ignore + // =================================================================================================== + */ +package +{ + import com.kaltura.KalturaClient; + import com.kaltura.base.vo.KalturaEntry; + import com.kaltura.config.KalturaConfig; + import com.kaltura.devicedetection.DeviceDetectionEvent; + import com.kaltura.net.streaming.events.ExNetConnectionEvent; + import com.kaltura.net.streaming.events.FlushStreamEvent; + import com.kaltura.net.streaming.events.RecordNetStreamEvent; + import com.kaltura.recording.business.BaseRecorderParams; + import com.kaltura.recording.controller.KRecordControl; + import com.kaltura.recording.controller.events.AddEntryEvent; + import com.kaltura.recording.controller.events.RecorderEvent; + import com.kaltura.recording.view.KRecordViewParams; + import com.kaltura.recording.view.UIComponent; + import com.kaltura.recording.view.View; + import com.kaltura.recording.view.ViewEvent; + import com.kaltura.recording.view.ViewState; + import com.kaltura.recording.view.ViewStatePreview; + import com.kaltura.utils.KConfigUtil; + import com.kaltura.utils.KUtils; + import com.kaltura.utils.ObjectHelpers; + import com.kaltura.vo.KalturaMediaEntry; + + import flash.display.Sprite; + import flash.display.Stage; + import flash.display.StageAlign; + import flash.display.StageScaleMode; + import flash.events.Event; + import flash.events.MouseEvent; + import flash.events.TimerEvent; + import flash.external.ExternalInterface; + import flash.filters.DropShadowFilter; + import flash.system.Security; + import flash.text.TextField; + import flash.text.TextFormat; + import flash.ui.ContextMenu; + import flash.ui.ContextMenuItem; + import flash.utils.Timer; + + import mx.core.Application; + import mx.utils.ObjectUtil; + + [SWF(width='320', height='240', frameRate='30', backgroundColor='#000000')] + [Frame(factoryClass="ApplicationLoader")] + + public class KRecord extends Sprite + { + public var pushParameters:Object; + + private var recordControl:KRecordControl=new KRecordControl(); + public var autoPreview:Boolean=false; + + + private var _message:TextField; + + private var _showErrorMessage:Boolean; + + private var messageX:Number = 0; + private var messageY:Number = 0; + + private var _view:View=new View; + private var _newViewState:String; + /** + * limit in seconds to recording time. 0 means no limit + */ + private var _limitRecord:Number = 0 ; + /** + * The timer for the recording limitation + */ + private var _limitRecordTimer:Timer; + + + public static const VERSION:String = "v1.5.10"; + + /** + *Constructor. + * @param init if true will automatically call startApplication and initialize application. + * + */ + public function KRecord(init:Boolean=true):void + { + trace("version:",VERSION); + Global.RECORD_CONTROL=recordControl; + addEventListener(Event.ADDED_TO_STAGE, build); + var myContextMenu:ContextMenu = new ContextMenu(); + var item:ContextMenuItem = new ContextMenuItem("Krecord "+VERSION,true); + myContextMenu.customItems.push(item); + this.contextMenu = myContextMenu; + + } + + private function build(evt:Event=null):void + { + Security.allowDomain("*"); + + var customContextMenu:ContextMenu=new ContextMenu(); + customContextMenu.hideBuiltInItems(); + var menuItem:ContextMenuItem=new ContextMenuItem(VERSION); + customContextMenu.customItems.push(menuItem); + + stageResize(null); + + var initParams:KRecordViewParams; + //read flashVars (uses these lines only when flashVars and ExternalInterface control is needed): + var paramObj:Object = !pushParameters ? root.loaderInfo.parameters : pushParameters; + var appparams:Object=ObjectHelpers.lowerNoUnderscore(paramObj); + if(appparams.showui=="false"){ + UIComponent.visibleSkin=false + } + if(appparams.showerrormessage=="true" || appparams.showerrormessage=="1"){ + _showErrorMessage=true + } + // view params: + var themeUrl:String=KConfigUtil.getDefaultValue(appparams.themeurl, "skin.swf"); + var localeUrl:String=KConfigUtil.getDefaultValue(appparams.localeurl, "locale.xml"); + var autoPreview:String=KConfigUtil.getDefaultValue(appparams.autopreview, "1"); + if(appparams.showpreviewtimer=="true" || appparams.showpreviewtimer =="0" ) + Global.SHOW_PREVIEW_TIMER = true; + Global.REMOVE_PLAYER=(appparams.removeplayer=="1" || appparams.removeplayer=="true"); + initParams = new KRecordViewParams(themeUrl, localeUrl, autoPreview); + + Global.DETECTION_DELAY = appparams.hasOwnProperty("detectiondelay") ? uint(appparams.detectiondelay) : 0; + + var configuration : KalturaConfig = new KalturaConfig(); + configuration.partnerId = appparams.pid; + configuration.ignoreNull = 1; + configuration.domain = KUtils.hostFromCode(appparams.host); + configuration.srvUrl = "api_v3/index.php" + configuration.ks = appparams.ks; + + if (!appparams.httpprotocol) + { + var url:String = root.loaderInfo.url; + configuration.protocol = isHttpURL(url) ? getProtocol(url) : "http"; + }else + { + configuration.protocol = appparams.httpprotocol; + } + configuration.protocol +="://"; + + Global.KALTURA_CLIENT = new KalturaClient(configuration); + + Global.DISABLE_GLOBAL_CLICK = (appparams.disableglobalclick=="1" || appparams.disableglobalclick=="true"); + Global.VIEW_PARAMS=initParams; + _view.addEventListener(ViewEvent.VIEW_READY, startApplication); + addChild(_view); + } + + public static function isHttpURL(url:String):Boolean + { + return url != null && + (url.indexOf("http://") == 0 || + url.indexOf("https://") == 0); + } + + private function onStartRecord(evt:ViewEvent):void + { + startRecording(); + _newViewState="recording"; + if (!recordControl.connecting) + _view.setState(_newViewState); + limitRecording(); + } + /** + * Stop recording automatically. + * This function is here so we dont change the signature of stopRecording function + * @param evt + * + */ + private function onRecordTimeComplete(evt:TimerEvent):void + { + trace("AUTO STOP AFTER ",_limitRecord," SECONDS") + stopRecording(); + callInterfaceDelegate("autoStopRecord",_limitRecord); + } + + + + private function onReRecord(evt:ViewEvent):void + { + startRecording(); + _newViewState="recording"; + if (!recordControl.connecting) + _view.setState(_newViewState); + } + + private function onStopRecord(evt:ViewEvent=null):void + { + stopRecording(); + _newViewState="preview"; + if (!recordControl.connecting) + _view.setState(_newViewState); + } + + + public static function getProtocol(url:String):String + { + var slash:int = url.indexOf("/"); + var indx:int = url.indexOf(":/"); + if (indx > -1 && indx < slash) + { + return url.substring(0, indx); + } + else + { + indx = url.indexOf("::"); + if (indx > -1 && indx < slash) + return url.substring(0, indx); + } + + return ""; + } + + private function onSave(evt:ViewEvent):void + { + recordControl.stopPreviewRecording(); + // get entry flashvars: + if (ExternalInterface.available) + { + try + { + var paramObj:Object = !pushParameters ? root.loaderInfo.parameters : pushParameters; + var appparams:Object=ObjectHelpers.lowerNoUnderscore(paramObj); + var entryName:String=KConfigUtil.getDefaultValue(appparams.entryname, ""); + var entryTags:String=KConfigUtil.getDefaultValue(appparams.entrytags, ""); + var entryDescription:String=KConfigUtil.getDefaultValue(appparams.entrydescription, ""); + var creditsScreenName:String=KConfigUtil.getDefaultValue(appparams.creditsscreenName, ""); + var creditsSiteUrl:String=KConfigUtil.getDefaultValue(appparams.creditssiteUrl, ""); + var categories:String=KConfigUtil.getDefaultValue(appparams.categories, ""); + var adminTags:String=KConfigUtil.getDefaultValue(appparams.admintags, ""); + var licenseType:String=KConfigUtil.getDefaultValue(appparams.licensetype, ""); + var credit:String=KConfigUtil.getDefaultValue(appparams.credit, ""); + var groupId:String=KConfigUtil.getDefaultValue(appparams.groupid, ""); + var partnerData:String=KConfigUtil.getDefaultValue(appparams.partnerdata, ""); + + addEntry(entryName, entryTags, entryDescription, creditsScreenName, creditsSiteUrl,categories, adminTags, licenseType, credit, groupId, partnerData) + } + catch (err:Error) + { + trace('Error reading flashVars and initializing KRecord via html and JS'); + } + } + else + { + addEntry("", "", "", "", "", "", "", "", "", "", ""); + } + + trace("SAVE"); + } + + + /** + * initializes the application. + */ + public function startApplication(event:Event=null):void + { + if (Global.PRELOADER && Global.PRELOADER.parent) + { + Global.PRELOADER.parent.removeChild(Global.PRELOADER); + Global.PRELOADER=null; + } + + _view.showPopupMessage(Global.LOCALE.getString("Dialog.Connecting")); + _view.addEventListener(ViewEvent.RECORD_START, onStartRecord); + _view.addEventListener(ViewEvent.RECORD_STOP, onStopRecord); + _view.addEventListener(ViewEvent.PREVIEW_SAVE, onSave); + _view.addEventListener(ViewEvent.PREVIEW_RERECORD, onReRecord); + + stage.align=StageAlign.TOP_LEFT; + stage.scaleMode=StageScaleMode.NO_SCALE; + var initParams:BaseRecorderParams; + //read flashVars (uses these lines only when flashVars and ExternalInterface control is needed): + if (ExternalInterface.available) + { + try + { + var paramObj:Object = !pushParameters ? root.loaderInfo.parameters : pushParameters; + var appparams:Object=ObjectHelpers.lowerNoUnderscore(paramObj); + autoPreview= !(appparams.autopreview=="0" || appparams.autopreview=="false"); + _limitRecord= KConfigUtil.getDefaultValue(appparams.limitrecord,0); + var hostUrl:String=KConfigUtil.getDefaultValue(appparams.host, "http://www.kaltura.com"); + var rtmpHost:String=KConfigUtil.getDefaultValue(appparams.rtmphost, "rtmp://www.kaltura.com"); + var ks:String=KConfigUtil.getDefaultValue(appparams.ks, ""); + var pid:String=KConfigUtil.getDefaultValue(appparams.pid, ""); + var subpid:String=KConfigUtil.getDefaultValue(appparams.subpid, ""); + var uid:String=KConfigUtil.getDefaultValue(appparams.uid, ""); + var kshowId:String=KConfigUtil.getDefaultValue(appparams.kshowid, "-1"); + var fmsApp:String=KConfigUtil.getDefaultValue(appparams.fmsapp, "oflaDemo"); + messageX=KConfigUtil.getDefaultValue(appparams.messagex, 0); + messageY=KConfigUtil.getDefaultValue(appparams.messagey, 0); + //init KRecord parameters: + initParams=new BaseRecorderParams(hostUrl, rtmpHost, ks, pid, subpid, uid, kshowId, fmsApp); + // Register External call + + ExternalInterface.addCallback("stopRecording", stopRecording); + ExternalInterface.addCallback("startRecording", startRecording); + ExternalInterface.addCallback("previewRecording", previewRecording); + ExternalInterface.addCallback("stopPreviewRecording", stopPreviewRecording); + ExternalInterface.addCallback("addEntry", addEntry); + ExternalInterface.addCallback("getRecordedTime", getRecordedTime); + ExternalInterface.addCallback("setQuality", setQuality); + ExternalInterface.addCallback("getMicrophones", getMicrophones); + ExternalInterface.addCallback("getMicrophoneActivityLevel", getMicrophoneActivityLevel); + ExternalInterface.addCallback("getMicrophoneGain", getMicrophoneGain); + ExternalInterface.addCallback("setMicrophoneGain", setMicrophoneGain); + ExternalInterface.addCallback("getCameras", getCameras); + ExternalInterface.addCallback("setActiveCamera", setActiveCamera); + ExternalInterface.addCallback("setActiveMicrophone", setActiveMicrophone); + + ExternalInterface.marshallExceptions=true; + callInterfaceDelegate("swfReady"); + trace('flashVars caught and JS functions registered to wrapper.\n' + 'objectId - ' + ExternalInterface.objectID); + + } + catch (err:Error) + { + trace('Error reading flashVars and initializing KRecord via html and JS'); + } + } + else + { + //init KRecord parameters, use this line in cases where you don't use flashVars and external JS control: + initParams=new BaseRecorderParams('http://www.kaltura.com', 'rtmp://www.kaltura.com', '', '', '', '', '-1', 'oflaDemo'); + } + + recordControl.initRecorderParameters=initParams; + recordControl.addEventListener(DeviceDetectionEvent.DETECTED_CAMERA, deviceDetected); + recordControl.addEventListener(DeviceDetectionEvent.DETECTED_MICROPHONE, deviceDetected); + recordControl.addEventListener(DeviceDetectionEvent.ERROR_CAMERA, deviceError); + + recordControl.addEventListener(DeviceDetectionEvent.CAMERA_DENIED, deviceError); + recordControl.addEventListener(DeviceDetectionEvent.MIC_DENIED, deviceError); + recordControl.addEventListener(DeviceDetectionEvent.ERROR_MICROPHONE, deviceError); + recordControl.addEventListener(ExNetConnectionEvent.NETCONNECTION_CONNECT_SUCCESS, connected); + recordControl.addEventListener(ExNetConnectionEvent.NETCONNECTION_CONNECT_FAILED, connectionError); + recordControl.addEventListener(ExNetConnectionEvent.NETCONNECTION_CONNECT_CLOSED, connectionError); + recordControl.addEventListener(RecordNetStreamEvent.NETSTREAM_RECORD_START, recordStart); + + recordControl.addEventListener(FlushStreamEvent.FLUSH_START, flushHandler); + recordControl.addEventListener(FlushStreamEvent.FLUSH_PROGRESS, flushHandler); + recordControl.addEventListener(FlushStreamEvent.FLUSH_COMPLETE, flushHandler); + + recordControl.addEventListener(RecordNetStreamEvent.NETSTREAM_PLAY_COMPLETE, previewEndHandler); + + recordControl.addEventListener(AddEntryEvent.ADD_ENTRY_RESULT, addEntryComplete); + recordControl.addEventListener(AddEntryEvent.ADD_ENTRY_FAULT, addEntryFailed); + recordControl.addEventListener(RecorderEvent.CONNECTING, onConnecting); + recordControl.addEventListener(RecorderEvent.CONNECTING_FINISH, onConnectingFinish); + recordControl.addEventListener(RecorderEvent.STREAM_ID_CHANGE, streamIdChange); + recordControl.addEventListener(RecorderEvent.UPDATE_RECORDED_TIME, updateRecordedTime); + trace("call deviceDetection"); + recordControl.deviceDetection(); + + if(this.stage == this.root.parent) + stage.addEventListener(Event.RESIZE, stageResize); + + dispatchEvent(new ViewEvent(ViewEvent.VIEW_READY, true)); + } + + + /** + *sets camera recording quality. + * @param quality An integer that specifies the required level of picture quality, + * as determined by the amount of compression being applied to each video frame. Acceptable values range from 1 + * (lowest quality, maximum compression) to 100 (highest quality, no compression). + * To specify that picture quality can vary as needed to avoid exceeding bandwidth, pass 0 for quality. + * @param bw Specifies the maximum amount of bandwidth that the current outgoing video feed can use, + * in bytes per second. To specify that Flash Player video can use as much bandwidth as needed to + * maintain the value of quality, pass 0 for bandwidth. The default value is 16384. + * @param w the width of the frame. + * @param h the height of the frame. + * @param fps frame per second to use. + * @param fps frame per second to use. + * @param gop The distance (in frames) between 2 keyframes + * @bufferTime This parameter compensates for lower connectivity or inconstant bandwidth + * so no content will be lost. + */ + public function setQuality(quality:int, bw:int, w:int, h:int, fps:Number, gop:int=25, bufferTime:Number=70):void + { + recordControl.bufferTime=bufferTime; + recordControl.setQuality(quality, bw, w, h, fps, gop); + } + + public function getMicrophones():String + { + return recordControl.getMicrophones().toString(); + } + + public function getCameras():String + { + return recordControl.getCameras().toString(); + } + + public function setActiveCamera(cameraName:String):void + { + recordControl.setActiveCamera(cameraName); + } + + public function setActiveMicrophone(microphoneName:String):void + { + recordControl.setActiveMicrophone(microphoneName); + } + + public function getMicrophoneActivityLevel():Number { + return recordControl.micophoneActivityLevel; + } + /** + * returns the volume of the microphone + * @return + * + */ + public function getMicrophoneGain():Number { + return recordControl.microphoneGain; + } + + /** + * sets the gain of the microphone + * @param val the given volume, between 0 to 100 + * + */ + public function setMicrophoneGain(val:String):void { + recordControl.microphoneGain = parseFloat(val); + } + + /** + *the duration of the recording in milliseconds. + */ + public function getRecordedTime():uint + { + return recordControl.recordedTime; + } + + public static function delegator(methodName:String, ... args):void + { + try + { + ExternalInterface.call("eval(window.delegator)", methodName , args); + } + catch(error:Error) + { + trace ("delegator: "+error.message); + } + } + + private function callInterfaceDelegate(methodName:String, ... args):void + { + delegator(methodName,args); + try { + var paramObj:Object = this.root.loaderInfo.parameters; + var appparams:Object = ObjectHelpers.lowerNoUnderscore(paramObj); + var delegate:String = KConfigUtil.getDefaultValue(paramObj.delegate, "window"); + ExternalInterface.call("eval(" + delegate + "." + methodName + ")", args); + } catch (err:Error) {trace (err.message)} + //print message on screen + var message:String = ""; + switch (methodName) + { + case DeviceDetectionEvent.ERROR_CAMERA: + message = "Error.CameraError"; + break; + case DeviceDetectionEvent.ERROR_MICROPHONE: + message = "Error.MichrophoneError"; + break; + case ExNetConnectionEvent.NETCONNECTION_CONNECT_FAILED: + message = "Error.ConnectionError"; + break; + case ExNetConnectionEvent.NETCONNECTION_CONNECT_CLOSED: + message = "Error.ConnectionClosed"; + break; + case RecorderEvent.CONNECTING: + message = "Dialog.Connecting"; + break; + case DeviceDetectionEvent.MIC_DENIED: + message = "Error.micDenied"; + break; + case DeviceDetectionEvent.CAMERA_DENIED: + message = "Error.cameraDenied"; + break; + } + //handle only the MIC_DENIED & CAMERA_DENIED since the UI is not ready for them yet QND + if(message && (methodName==DeviceDetectionEvent.MIC_DENIED + || methodName==DeviceDetectionEvent.ERROR_MICROPHONE + || methodName==DeviceDetectionEvent.CAMERA_DENIED + || methodName==DeviceDetectionEvent.ERROR_CAMERA)) + { + if(!_message) + { + _message= new TextField(); + _message.width = this.width; + _message.height = this.height; + _message.x = messageX; + _message.y = messageY; + var tf:TextFormat = new TextFormat(); + tf.color = 0xFFFFFF; + //add drop shadow filter to message + var my_shadow:DropShadowFilter = new DropShadowFilter(); + my_shadow.color = 0x000000; + my_shadow.blurY = 3; + my_shadow.blurX = 3; + my_shadow.angle = 45; + my_shadow.alpha = 1; + my_shadow.distance = 2; + var filtersArray:Array = new Array(my_shadow); + _message.filters = filtersArray; + + } + + _message.text = Global.LOCALE.getString(message); + _message.setTextFormat(tf); + if(_showErrorMessage) //show this message only if showErrorMessege is set to true + addChild(_message); + } + } + + private function stageResize(event:Event):void + { + //set the _view width and height because any view resize by it's parent + _view.width = _view.viewWidth=stage.stageWidth; + _view.height = _view.viewHeight=stage.stageHeight; + + graphics.clear(); + graphics.beginFill(0x000000); + graphics.drawRect(0, 0, _view.viewWidth, _view.viewHeight); + graphics.endFill(); + + if (recordControl && recordControl.video) + { + if (contains(recordControl.video)) + removeChild(recordControl.video); + recordControl.resizeVideo(_view.viewWidth, _view.viewHeight); + addChildAt(recordControl.video, 0); + } + } + + private function deviceError(event:DeviceDetectionEvent):void + { + try + { + trace(event.type); + this.callInterfaceDelegate(event.type); + } + catch (err:Error) + { + trace(err.message) + } + +// if (event.type == DeviceDetectionEvent.ERROR_CAMERA) +// { +// _view.showPopupError(Global.LOCALE.getString("Error.CameraError")); +// } + + switch (event.type){ + case DeviceDetectionEvent.ERROR_CAMERA: + _view.showPopupError(Global.LOCALE.getString("Error.CameraError")); + break; + case DeviceDetectionEvent.ERROR_MICROPHONE: + case DeviceDetectionEvent.MIC_DENIED: + recordControl.setActiveMicrophone(recordControl.getMicrophones()[0]); + break; + } + dispatchEvent(event.clone()); + } + + private function deviceDetected(event:DeviceDetectionEvent):void + { + + //add the detected mic notification + if(event.type == DeviceDetectionEvent.DETECTED_MICROPHONE) + { + try + { + this.callInterfaceDelegate(DeviceDetectionEvent.DETECTED_MICROPHONE); + } + catch (err:Error) + { + trace(err.message) + } + } + + + + + if (event.type == DeviceDetectionEvent.DETECTED_CAMERA) + { + stageResize(null); + setQuality(85, 0, 336, 252, 25); + recordControl.connectToRecordingServie(); +// _view.setState( "start" ); + try + { + this.callInterfaceDelegate("deviceDetected"); + } + catch (err:Error) + { + trace(err.message) + } + try + { + this.callInterfaceDelegate(DeviceDetectionEvent.DETECTED_CAMERA); + } + catch (err:Error) + { + trace(err.message) + } + } + dispatchEvent(event.clone()); + } + + private function connected(event:ExNetConnectionEvent):void + { + _view.setState("start"); + trace(event.type); + try + { + this.callInterfaceDelegate("connected"); + } + catch (err:Error) + { + trace(err.message) + } + dispatchEvent(event.clone()); + } + + private function connectionError(event:ExNetConnectionEvent):void + { + trace(event.type) + try + { + this.callInterfaceDelegate(event.type); + } + catch (err:Error) + { + trace(err.message) + } + + + if(event.type == ExNetConnectionEvent.NETCONNECTION_CONNECT_FAILED) + _view.showPopupError(Global.LOCALE.getString("Error.ConnectionError")); + if(event.type == ExNetConnectionEvent.NETCONNECTION_CONNECT_CLOSED) + _view.showPopupError(Global.LOCALE.getString("Error.ConnectionClosed")); + dispatchEvent(event.clone()); + } + + /** + * start publishing the audio. + */ + public function startRecording():void + { + _newViewState = "recording" + _view.setState(_newViewState); + trace("RECORD START"); + recordControl.recordNewStream(); + limitRecording(); + + } + + /** + * Check if this instance needs to limit the time and start the timer if needed. + */ + private function limitRecording():void + { + if(_limitRecord && !_limitRecordTimer) + { + _limitRecordTimer = new Timer(_limitRecord*1000,1); + _limitRecordTimer.addEventListener(TimerEvent.TIMER_COMPLETE,onRecordTimeComplete); + _limitRecordTimer.start(); + } + } + private function recordStart(event:RecordNetStreamEvent):void + { + try + { + this.callInterfaceDelegate("recordStart"); + } + catch (err:Error) + { + trace(err.message) + } + dispatchEvent(event.clone()); + } + + /** + * stop publishing to the server. + */ + public function stopRecording():void + { + if(_limitRecordTimer) + { + _limitRecordTimer.removeEventListener(TimerEvent.TIMER_COMPLETE,onRecordTimeComplete); + _limitRecordTimer.stop(); + _limitRecordTimer = null; + } + + _newViewState = "preview" + _view.setState(_newViewState); + trace("KRecord==>stopRecording()"); + recordControl.stopRecording(); + } + + private function flushHandler(event:FlushStreamEvent):void + { + trace(event.type + " : " + event.bufferSize + " / " + event.totalBuffer); + if (event.type == FlushStreamEvent.FLUSH_COMPLETE) + { + /*if (autoPreview) + previewRecording();*/ + try + { + + this.callInterfaceDelegate("flushComplete"); + } + catch (err:Error) + { + trace(err.message); + } + dispatchEvent(event.clone()); + + } + } + + /** + * show loader connecting when needed. + */ + private function onConnecting(event:Event):void + { + this.callInterfaceDelegate("connecting"); + _view.showPopupMessage(Global.LOCALE.getString("Dialog.Connecting")); + dispatchEvent(event.clone()); + } + + /** + * remove loader connecting when needed and get back to the current view state. + */ + private function onConnectingFinish(event:Event):void + { + this.callInterfaceDelegate("connectingFinish"); + _view.setState(_newViewState); + dispatchEvent(event.clone()); + } + + /** + * play the recorded stream. + */ + public function previewRecording():void + { + trace("PREVIEW START"); + var currentState:Object = _view.getState(); + if(currentState is ViewStatePreview) + { + (currentState as ViewStatePreview).player.play(new MouseEvent("click")); + } + + } + /** + * stop playing the recorded stream. + */ + public function stopPreviewRecording():void + { + var currentState:Object = _view.getState(); + if(currentState is ViewStatePreview) + { + (currentState as ViewStatePreview).player.stop(); + } + } + + private function previewEndHandler(event:RecordNetStreamEvent):void + { + trace('preview: ' + event.type); + + try + { + this.callInterfaceDelegate("previewEnd"); + } + catch (err:Error) + { + trace(err.message) + } + dispatchEvent(event.clone()); + } + + /** + * add the last recording as a new Kaltura entry in the Kaltura Network. + * @param entry_name the name for the new added entry. + * @param entry_tags user tags for the newly created entry. + * @param entry_description description of the newly created entry. + * @param credits_screen_name for anonymous user applications - the screen name of the user that contributed the entry. + * @param credits_site_url for anonymous user applications - the website url of the user that contributed the entry. + * @param categories Categories. comma seperated string + * @param admin_tags admin tags for the newly created entry. + * @param license_type the content license type to use (this is arbitrary to be set by the partner). + * @param credit custom partner credit feild, will be used to attribute the contributing source. + * @param group_id used to group multiple entries in a group. + * @param partner_data special custom data for partners to store. + */ + public function addEntry(entry_name:String='', entry_tags:String='', entry_description:String='', credits_screen_name:String='', credits_site_url:String='', categories:String="", admin_tags:String='', license_type:String='', credit:String='', group_id:String='', partner_data:String=''):void + { + if (entry_name == '') + entry_name='recorded_entry_pid_' + recordControl.initRecorderParameters.baseRequestData.partner_id + (Math.floor(Math.random() * 1000000)).toString(); + + this.callInterfaceDelegate("beforeAddEntry"); + recordControl.addEntry(entry_name, entry_tags, entry_description, credits_screen_name, credits_site_url, categories, admin_tags, license_type, credit, group_id, partner_data); + } + + private function addEntryFailed(event:AddEntryEvent):void + { + dispatchEvent(event.clone()); + this.callInterfaceDelegate("addEntryFailed",{errorCode:event.info.error.errorCode , errorMsg:event.info.error.errorMsg}); + } + + private function addEntryComplete(event:AddEntryEvent):void + { + var entry:KalturaMediaEntry=event.info as KalturaMediaEntry; + if (entry) + { + try + { + this.callInterfaceDelegate("addEntryComplete", event.info); + } + catch (err:Error) + { + trace(err.message) + } + trace("Your new entry is: " + entry.entryId + "\nthumb: " + entry.thumbnailUrl); + } + else + { + try + { + this.callInterfaceDelegate("addEntryFail", event.info); + } + catch (err:Error) + { + trace(err.message) + } + trace(ObjectUtil.toString(event.info)); + } + dispatchEvent(event.clone()); + } + + private function streamIdChange(event:RecorderEvent):void + { + dispatchEvent(event.clone()); + } + + private function updateRecordedTime(event:RecorderEvent):void + { + dispatchEvent(event.clone()); + } + } +} diff --git a/KalturaRecord/src/KRecordLocaleDefault.as b/KalturaRecord/src/KRecordLocaleDefault.as new file mode 100644 index 0000000..081cf4e --- /dev/null +++ b/KalturaRecord/src/KRecordLocaleDefault.as @@ -0,0 +1,67 @@ +package +{ + import com.kaltura.utils.Locale; + + + public class KRecordLocaleDefault extends Locale + { + private var _defaults:XML = + + + + + Button.StopRecord + Click anywhere to stop recording + + + + Button.StartRecord + Click anywhere to start recording + + + + Button.Save + Save + + + + Button.Yes + Yes + + + + Button.No + No + + + + Dialog.Overwrite + Record again without saving? + + + + Dialog.Connecting + Connecting... + + + + Error.ConnectionError + Connection error. Please try again later + + + + Error.CameraError + No camera detected + + + + + + + public function KRecordLocaleDefault() + { + super(_defaults); + } + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/com/kaltura/devicedetection/DeviceDetectionEvent.as b/KalturaRecord/src/com/kaltura/devicedetection/DeviceDetectionEvent.as new file mode 100644 index 0000000..5ad154e --- /dev/null +++ b/KalturaRecord/src/com/kaltura/devicedetection/DeviceDetectionEvent.as @@ -0,0 +1,59 @@ +/* +// =================================================================================================== +// _ __ _ _ +// | |/ /__ _| | |_ _ _ _ _ __ _ +// | ' . +// +// @ignore +// =================================================================================================== +*/ +package com.kaltura.devicedetection +{ + import flash.events.Event; + import flash.media.Camera; + import flash.media.Microphone; + + public class DeviceDetectionEvent extends Event + { + static public var DETECTED_MICROPHONE:String = "detectedMicrophone"; + static public var DETECTED_CAMERA:String = "detectedCamera"; + + static public var ERROR_MICROPHONE:String = "errorMicrophone"; + static public var ERROR_CAMERA:String = "errorCamera"; + static public var MIC_DENIED:String = "micDenied"; + static public var CAMERA_DENIED:String = "cameraDenied"; + + public var detectedDevice:Object; + + public function DeviceDetectionEvent(type:String, device:Object):void + { + super(type, true, false); + detectedDevice = device; + } + + override public function clone():Event + { + return new DeviceDetectionEvent (this.type, detectedDevice); + } + } +} \ No newline at end of file diff --git a/KalturaRecord/src/com/kaltura/devicedetection/DeviceDetector.as b/KalturaRecord/src/com/kaltura/devicedetection/DeviceDetector.as new file mode 100644 index 0000000..6b44e08 --- /dev/null +++ b/KalturaRecord/src/com/kaltura/devicedetection/DeviceDetector.as @@ -0,0 +1,462 @@ +/* +// =================================================================================================== +// _ __ _ _ +// | |/ /__ _| | |_ _ _ _ _ __ _ +// | ' . +// +// @ignore +// =================================================================================================== +*/ +package com.kaltura.devicedetection +{ + import flash.display.BitmapData; + import flash.events.EventDispatcher; + import flash.events.StatusEvent; + import flash.events.TimerEvent; + import flash.external.ExternalInterface; + import flash.geom.Rectangle; + import flash.media.Camera; + import flash.media.Microphone; + import flash.media.Video; + import flash.net.NetConnection; + import flash.net.NetStream; + import flash.system.Security; + import flash.system.SecurityPanel; + import flash.utils.Timer; + import flash.utils.clearTimeout; + import flash.utils.setTimeout; + + /** + * dispatched to notify an active microphone device was detetceted. + * @eventType com.kaltura.devicedetection.DeviceDetectionEvent.DETECTED_MICROPHONE + */ + [Event(name="detectedMicrophone", type="com.kaltura.devicedetection.DeviceDetectionEvent")] + /** + * dispatched to notify an active camera device was detected. + * @eventType com.kaltura.devicedetection.DeviceDetectionEvent.DETECTED_CAMERA + */ + [Event(name="detectedCamera", type="com.kaltura.devicedetection.DeviceDetectionEvent")] + /** + * dispatched to notify an error of detecting an active microphone. + * @eventType com.kaltura.devicedetection.DeviceDetectionEvent.ERROR_MICROPHONE + */ + [Event(name="errorMicrophone", type="com.kaltura.devicedetection.DeviceDetectionEvent")] + /** + * dispatched to notify an error of detecting an active camera. + * @eventType com.kaltura.devicedetection.DeviceDetectionEvent.ERROR_CAMERA + */ + [Event(name="errorCamera", type="com.kaltura.devicedetection.DeviceDetectionEvent")] + + public class DeviceDetector extends EventDispatcher + { + public var webCam:Camera = null; + private var camerasNumber:int = Camera.names.length; + private var testedCameraIndex:int = -1; + private var testedCamera:Camera; + private var testedVideo:Video = new Video (50, 50); + private var testRect:Rectangle = new Rectangle (0, 0, 50, 50); + private var testedBitmapData:BitmapData = new BitmapData (50, 50, false, 0x0); + private var blackBitmapData:BitmapData = new BitmapData (50, 50, false, 0x0); + private var delayDetectCameraIndex:uint = 0; + private var cameraFails:uint = 0; + public var maxCameraFails:uint = 3; + + public var microphone:Microphone = null; + private var microphonesNumber:int = Microphone.names.length; + private var testedMicrophoneIndex:int = 0; + private var testedMicrophone:Microphone; + private var mostActiveMicrophoneIndex:int = -1; + private var mostActiveMicrophoneActivity:int = 0; + private var testNetConnection:NetConnection; + private var testNetStream:NetStream; + private var useSilenceMicrophoneDetection:Boolean = false; + private var delayDetectMicrphoneIndex:uint = 0; + private var microphoneFails:uint = 0; + public var maxMicrophoneFails:uint = 3; + + private var delayTime:uint; + private var delayAfterFail:uint; + private var MicTimer:Timer; + private var everySecTimer:Timer; + + + ////// + // CCCCCCCCC AAAAAAAAAAA MMMMMM MMMMMM + // CCCCCCCCC AAAAAAAAAAA MMMMMMMMMM MMMMMMMMMM + // CCC AAA AAA MMMM MMMMM MMMM + // CCC AAAAAAAAAAA MMM MMM MMM + // CCCCCCCCC AAA AAA MMM M MMM + // CCCCCCCCC AAA AAA MMM MMM + ////// + + public function detectCamera (delay:uint = 500):void + { + delayTime = delay; + delayAfterFail = delay * 2; + testedCameraIndex = -1; + if (delayDetectCameraIndex != 0) + clearTimeout(delayDetectCameraIndex); + testedBitmapData = new BitmapData (testRect.width, testRect.height, false, 0x0); + blackBitmapData = new BitmapData (testRect.width, testRect.height, false, 0x0); + blackBitmapData.fillRect(testRect, 0x0); + detectNextCamera (); + } + + private function detectNextCamera ():void + { + cameraFails = 0; + + if (webCam) + { + dispatchCameraSuccess (); + return; + } + + if (testedCameraIndex > 0 && testedCamera != null) + testedCamera.removeEventListener(StatusEvent.STATUS, statusCameraHandler); + + if ((++testedCameraIndex) >= camerasNumber) + { + //we didn't find any camera on the system.. + dispatchCameraError (DeviceDetectionEvent.ERROR_CAMERA); + return; + } + + testedCamera = Camera.getCamera(testedCameraIndex.toString()); + + if (testedCamera == null) + { + if (camerasNumber > 0) + { + //there are devices on the system but we don't get access directly to them... + //let the user set the access to the default camera: + // NOTE: this should never happen here, because we use the specific access to the camera object + // rather than using the default getCamera (); +// Security.showSettings(SecurityPanel.CAMERA); + dispatchCameraError(DeviceDetectionEvent.CAMERA_DENIED); + } else { + //we don't have any camera device! + dispatchCameraError (DeviceDetectionEvent.ERROR_CAMERA); + } + return; + } + + testedBitmapData.fillRect(testRect, 0x0); + testedVideo.attachCamera(null); + testedVideo.clear(); + testedCamera.addEventListener(StatusEvent.STATUS, statusCameraHandler); + testedVideo.attachCamera(testedCamera); + + if (!testedCamera.muted) + { + trace("User selected Accept already."); + delay_testCameraImage (); + } /*else { + //the user selected not to allow access to the devices. +// Security.showSettings(SecurityPanel.PRIVACY); +// dispatchCameraError (DeviceDetectionEvent.CAMERA_DENIED); + }*/ + } + + private function statusCameraHandler (event:StatusEvent):void + { + switch (event.code) + { + case "Camera.Muted": + trace("Camera: User clicked Deny."); + dispatchCameraError (DeviceDetectionEvent.CAMERA_DENIED); + break; + + case "Camera.Unmuted": + trace("Camera: User clicked Accept."); + delay_testCameraImage (); + break; + } + } + + /** + * delays the image test. + *

the system takes abit of time to initialize the connection to the physical camera and return image + * so we give the camera 1.5 seconds to actually be attached and return an image + * unfortunatly we don't have any event from the flash player that notify a physical initialization and that image was given. + * we additionaly give more time for slower machines (or cameras) if we fail. + * you can set the maximum fail tryouts by setting the maxFails variable.

+ */ + private function delay_testCameraImage ():void + { + delayDetectCameraIndex = setTimeout (testCameraImage, (cameraFails > 0) ? delayAfterFail : delayTime); + } + + private function testCameraImage ():void + { + testedBitmapData.draw(testedVideo); + var testResult:Object = testedBitmapData.compare(blackBitmapData); + trace ("camera test: " + testedCameraIndex); + + // Added currentFPS check to make sure if the camera is active. + if (testResult is BitmapData || testedCamera.currentFPS != 0) + { + //it's different, we have an image! + dispatchCameraSuccess (); + } else { + //camera is not available for some reson, we don't get any image. + // move to check the next camera + if ((++cameraFails) < maxCameraFails) + { + delay_testCameraImage (); + } else { + detectNextCamera (); + } + } + } + + private function dispatchCameraSuccess ():void + { + disposeCamera (); + webCam = Camera.getCamera(testedCameraIndex.toString()); + dispatchEvent(new DeviceDetectionEvent (DeviceDetectionEvent.DETECTED_CAMERA, webCam)); + } + + private function dispatchCameraError (errorEventType:String):void + { + disposeCamera (); + webCam = null; +// dispatchEvent(new DeviceDetectionEvent (DeviceDetectionEvent.ERROR_CAMERA, webCam)); + dispatchEvent(new DeviceDetectionEvent (errorEventType, webCam)); + trace("madafaka!!!!!!!!!!!!!!!!!!!!!!!"); + ExternalInterface.call("noCamerasFound") + } + + private function disposeCamera ():void + { + if (testedCamera) + testedCamera.removeEventListener(StatusEvent.STATUS, statusCameraHandler); + testedCamera = null; + testedVideo.attachCamera(null); + testedVideo.clear(); + if (blackBitmapData) + blackBitmapData.dispose(); + if (testedBitmapData) + testedBitmapData.dispose(); + } + + + ////// + // MMMMMM MMMMMM IIIIIIIIIII CCCCCCCCC + // MMMMMMMMMM MMMMMMMMMM IIIIIIIIIII CCCCCCCCC + // MMMM MMMMM MMMM III CCC + // MMM MMM MMM III CCC + // MMM M MMM IIIIIIIIIII CCCCCCCCC + // MMM MMM IIIIIIIIIII CCCCCCCCC + ////// + + public function detectMicrophone ():void + { + testedMicrophone=Microphone.getMicrophone(testedMicrophoneIndex); + if(!testedMicrophone) + { + dispatchEvent(new DeviceDetectionEvent (DeviceDetectionEvent.ERROR_MICROPHONE, null)); + return; + } + testedMicrophone.setUseEchoSuppression(true) + testedMicrophone.setLoopBack(true);//this is for provoking some activity input when it's not streaming + testedMicrophone.setSilenceLevel(5); + testedMicrophone.gain=90 + var timeLapse:String= ""//Application.application.parameters.testLapse; + var timeValue:Number + ExternalInterface.addCallback("openSettings",openSettings); + if (timeLapse != null){ + timeValue=Number(timeLapse) + MicTimer=new Timer (20000,0); + everySecTimer=new Timer(timeValue/1000); + } + else + { + MicTimer=new Timer (20000,0); + everySecTimer=new Timer(1000,20); + } + MicTimer.addEventListener(TimerEvent.TIMER, checkMicActivity); + everySecTimer.addEventListener(TimerEvent.TIMER, onEverySec); + if (testedMicrophone.muted==false) + { + addTimers() + } + else + { + testedMicrophone.addEventListener(StatusEvent.STATUS, statusHandler); + } + } + + private function addTimers():void + { + MicTimer.start() + everySecTimer.start() + } + + private function stopTimers():void + { + MicTimer.stop() + everySecTimer.stop() + } + + private function statusHandler(event:StatusEvent):void + { + trace(event.code) + if (event.code=="Microphone.Unmuted") + { + addTimers() + trace("The user allows open the mic...") + } + + if(event.code=="Microphone.Muted") + { + trace("The user does not allows to use the mic..."); + ////HERE A JS alert: "Are you sure you don't allow the mic to be open? You won't be able to record with audio.. + try { + //KRecord.delegator("micDenied"); + dispatchEvent(new DeviceDetectionEvent (DeviceDetectionEvent.MIC_DENIED, null)); + ExternalInterface.call("micDenied"); + } + catch(errObject:Error) { + trace(errObject.message); + } + } + + } + + public function openSettings():void + { + Security.showSettings("2"); + } + + + private function checkMicActivity(timerEvent:TimerEvent):void + { + if (testedMicrophone.activityLevel<2) + { + detectNextMicrophone() + } + else + { + success() + } + } + + private function onEverySec(timerEvent:TimerEvent):void + { + if (testedMicrophone.activityLevel>2) + { + success() + } + } + + private function success():void + { + stopTimers() + dispatchMicrophoneSuccess () + try { + ExternalInterface.call("workingMicFound"); + } + catch(errObject:Error) { + trace(errObject.message); + } + trace("working Mic Found") + } + + private function detectNextMicrophone ():void + { + testedMicrophoneIndex++ + if (testedMicrophoneIndex < microphonesNumber) + { + detectMicrophone () + } + else + { + ////HERE A JS alert: "Not Working mics were found on your computer" Please check the configuration + try { + openSettings() + ExternalInterface.call("noMicsFound"); + } + catch(errObject:Error) { + trace(errObject.message); + } + dispatchEvent(new DeviceDetectionEvent (DeviceDetectionEvent.ERROR_MICROPHONE, null)); + } + return; + } + + + private function dispatchMicrophoneSuccess ():void + { + disposeMicrophone() + microphone = Microphone.getMicrophone(testedMicrophoneIndex); + microphone.setUseEchoSuppression(true); + microphone.gain=90 + dispatchEvent(new DeviceDetectionEvent (DeviceDetectionEvent.DETECTED_MICROPHONE, microphone)); + ExternalInterface.addCallback("getMicophoneActivityLevel",getActivityNow) + microphone.setSilenceLevel(0); + } + + private function getActivityNow():int + { + var activ:int=microphone.activityLevel; + return activ; + } + + + private function disposeMicrophone ():void + { + if (testedMicrophone) + { + testedMicrophone.setLoopBack(false); + testedMicrophone.gain=0 + } + testedMicrophone = null; + } + + + /////// ============= singletone + /** + *Constructor + getInsance. + */ + static private var _instance:DeviceDetector; + + public function DeviceDetector():void + { + if (_instance) + throw (new Error ("you can't instantiate singletone more than once, use getInstance instead.")); + + testedVideo.smoothing = false; + testedVideo.deblocking = 1; + } + + static public function getInstance ():DeviceDetector + { + if (!_instance) + _instance = new DeviceDetector (); + return _instance; + } + + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/com/kaltura/recording/business/AddEntryDelegate.as b/KalturaRecord/src/com/kaltura/recording/business/AddEntryDelegate.as new file mode 100644 index 0000000..3b02f77 --- /dev/null +++ b/KalturaRecord/src/com/kaltura/recording/business/AddEntryDelegate.as @@ -0,0 +1,153 @@ +/* +// =================================================================================================== +// _ __ _ _ +// | |/ /__ _| | |_ _ _ _ _ __ _ +// | ' . +// +// @ignore +// =================================================================================================== +*/ +package com.kaltura.recording.business +{ + import com.kaltura.base.vo.KalturaEntry; + import com.kaltura.net.TemplateURLVariables; + import com.kaltura.recording.business.interfaces.IResponder; + + import flash.events.Event; + import flash.events.IOErrorEvent; + import flash.events.SecurityErrorEvent; + import flash.net.URLLoader; + import flash.net.URLRequest; + import flash.net.URLRequestMethod; + + public class AddEntryDelegate + { + private var responder:IResponder; + private var _loader:URLLoader = new URLLoader; + + public function AddEntryDelegate(_responder:IResponder) + { + responder = _responder; + _loader.addEventListener(Event.COMPLETE, loaderCompleteHandler); + _loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler); + _loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler); + } + + /** + * adds a new entry to the Kaltura Network. + * @param baseParams the recorder base parameters (containing partner and session info). + * @param mediaType the media type of the newly created entry (video, audio, image etc). + * @param entryName the name for the new added entry. + * @param fileName the file name of the newly created entry as it exist on the server after upload/record. + * @param entryTags user tags for the newly created entry. + * @param entryDescription description of the newly created entry. + * @param fromTime for streaming media - used to trim the new entry from the start, in milliseconds. + * @param toTime for streaming media - used to trim the new entry from the end, in milliseconds. + * @param mediaSource the Entry Media Source as specified by the EntryMediaSource enum, for webcam = 2; + * @param creditsScreenName for anonymous user applications - the screen name of the user that contributed the entry. + * @param creditsSiteUrl for anonymous user applications - the website url of the user that contributed the entry. + * @param thumbOffset for streaming media - used to decide from what second to capture a thumbnail. + * @param adminTags admin tags for the newly created entry. + * @param licenseType the content license type to use (this is arbitrary to be set by the partner). + * @param credit custom partner credit feild, will be used to attribute the contributing source. + * @param groupId used to group multiple entries in a group. + * @param partnerData special custom data for partners to store. + */ + public function addEntry (baseParams:BaseRecorderParams, mediaType:int, entryName:String, fileName:String, + entryTags:String, entryDescription:String, fromTime:Number = -1, toTime:Number = -1, + mediaSource:int = 2, creditsScreenName:String = '', creditsSiteUrl:String = '', + thumbOffset:int = -1, adminTags:String = '', licenseType:String = '', credit:String = '', + groupId:String = '', partnerData:String = ''):void + { + var params:TemplateURLVariables = new TemplateURLVariables(baseParams.baseRequestData); + params["kshow_id"] = baseParams.kshowid; + params["quick_edit"] = 0; + if (creditsScreenName != '') + params["credits_screen_name"] = creditsScreenName; + if (creditsSiteUrl != '') + params["credits_site_url"] = creditsSiteUrl; + params["entry1_filename"] = fileName; + params["entry1_description"] = entryDescription; + params["entry1_tags"] = entryTags; + params["entry1_mediaType"] = mediaType; + params["entry1_source"] = mediaSource; + params["entry1_name"] = entryName; + if (licenseType != '') + params["entry1_licenseType"] = licenseType; + if (credit != '') + params["entry1_credit"] = credit; + if (groupId != '') + params["entry1_groupId"] = groupId; + if (partnerData != '') + params["entry1_partnerData"] = partnerData; + if (thumbOffset > -1) + params["entry1_thumbOffset"] = thumbOffset; + if (adminTags != '') + params["entry1_adminTags"] = adminTags; + if (fromTime >= 0) + params["entry1_from_time"] = fromTime; + if (toTime >= 0) + params["entry1_to_time"] = toTime; + var request:URLRequest = new URLRequest (baseParams.addEntryUrl); + request.method = URLRequestMethod.GET; + request.data = params; + _loader.load(request); + } + + private function loaderCompleteHandler (event:Event):void + { + var resultXml:XML = new XML (event.target.data); + // if the server returned an error: + if (resultXml.error.children().length() > 0) + { + fault (resultXml.error.children()); + return; + } + var entries:Array = []; + var allEntries:XMLList = resultXml.result.entries.children(); + var entry:XML; + var entryInfo:KalturaEntry; + for each ( entry in allEntries ) + { + entryInfo = new KalturaEntry (entry); + entries.push(entryInfo); + } + responder.result(entries); + } + + private function fault (info:Object):void + { + responder.fault(info); + } + + private function ioErrorHandler(event:IOErrorEvent):void + { + fault (event); + } + + private function securityErrorHandler(event:SecurityErrorEvent):void + { + fault (event); + } + } +} \ No newline at end of file diff --git a/KalturaRecord/src/com/kaltura/recording/business/BaseRecorderParams.as b/KalturaRecord/src/com/kaltura/recording/business/BaseRecorderParams.as new file mode 100644 index 0000000..3bf3732 --- /dev/null +++ b/KalturaRecord/src/com/kaltura/recording/business/BaseRecorderParams.as @@ -0,0 +1,73 @@ +/* +// =================================================================================================== +// _ __ _ _ +// | |/ /__ _| | |_ _ _ _ _ __ _ +// | ' . +// +// @ignore +// =================================================================================================== +*/ +package com.kaltura.recording.business +{ + public class BaseRecorderParams + { + public var host:String; + public var rtmpHost:String; + public var addEntryUrl:String; + public var baseRequestData:Object; + public var kshowid:String; + + /** + * Constructor. + * @param _host Kaltura api host. + * @param rtmp_host Streaming service for the recording. + * @param _ks Kaltura Session id. + * @param _partnerid Kaltura Partner id. + * @param _subpid Kaltura Sub Partner id. + * @param _uid Partner User id. + * @param _kshowid kshow to associate the recordings to. + * @param recording_application the name of the recording application on the streaming server. + */ + public function BaseRecorderParams (_host:String, rtmp_host:String, _ks:String, _partnerid:String, + _subpid:String, _uid:String, _kshowid:String, recording_application:String = "oflaDemo"):void + { + host = _host; + var hasHttp:Boolean = host.indexOf("http://") > -1; + if (rtmp_host == '') + rtmpHost = hasHttp ? "rtmp://" + host.substr(7) + "/" + recording_application : "rtmp://" + host + "/" + recording_application; + else + rtmpHost = rtmp_host + "/" + recording_application; + if (!hasHttp) + host = "http://" + host; + baseRequestData = + { + ks: _ks, + partner_id: _partnerid, + subp_id: _subpid, + uid: _uid + }; + kshowid = _kshowid; + addEntryUrl = host + "/index.php/partnerservices2/addentry"; + } + } +} \ No newline at end of file diff --git a/KalturaRecord/src/com/kaltura/recording/business/interfaces/IResponder.as b/KalturaRecord/src/com/kaltura/recording/business/interfaces/IResponder.as new file mode 100644 index 0000000..651a5b4 --- /dev/null +++ b/KalturaRecord/src/com/kaltura/recording/business/interfaces/IResponder.as @@ -0,0 +1,37 @@ +/* +// =================================================================================================== +// _ __ _ _ +// | |/ /__ _| | |_ _ _ _ _ __ _ +// | ' . +// +// @ignore +// =================================================================================================== +*/ +package com.kaltura.recording.business.interfaces +{ + public interface IResponder + { + function result (data:Object):void; + function fault (info:Object):void; + } +} \ No newline at end of file diff --git a/KalturaRecord/src/com/kaltura/recording/controller/IRecordControl.as b/KalturaRecord/src/com/kaltura/recording/controller/IRecordControl.as new file mode 100644 index 0000000..0b614f3 --- /dev/null +++ b/KalturaRecord/src/com/kaltura/recording/controller/IRecordControl.as @@ -0,0 +1,25 @@ +package com.kaltura.recording.controller +{ +public interface IRecordControl +{ + + function get playheadTime():Number; + function get recordedTime():uint; + function get blackRecordTime():uint; + + function previewRecording():void; + function pausePreviewRecording():void; + function resume():void; + function stopPreviewRecording ():void; + function seek( offset:Number):void; + + + function clearVideoAndSetCamera():void; //Boaz addition + + + function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void; + function removeEventListener(type:String, listener:Function, useCapture:Boolean=false):void; + + +} +} \ No newline at end of file diff --git a/KalturaRecord/src/com/kaltura/recording/controller/KRecordControl.as b/KalturaRecord/src/com/kaltura/recording/controller/KRecordControl.as new file mode 100644 index 0000000..d350946 --- /dev/null +++ b/KalturaRecord/src/com/kaltura/recording/controller/KRecordControl.as @@ -0,0 +1,809 @@ +/* +// =================================================================================================== +// _ __ _ _ +// | |/ /__ _| | |_ _ _ _ _ __ _ +// | ' . +// +// @ignore +// =================================================================================================== +*/ +package com.kaltura.recording.controller +{ + import com.kaltura.KalturaClient; + import com.kaltura.commands.media.MediaAddFromRecordedWebcam; + import com.kaltura.devicedetection.DeviceDetectionEvent; + import com.kaltura.devicedetection.DeviceDetector; + import com.kaltura.events.KalturaEvent; + import com.kaltura.net.streaming.ExNetConnection; + import com.kaltura.net.streaming.RecordNetStream; + import com.kaltura.net.streaming.events.ExNetConnectionEvent; + import com.kaltura.net.streaming.events.FlushStreamEvent; + import com.kaltura.net.streaming.events.RecordNetStreamEvent; + import com.kaltura.recording.business.AddEntryDelegate; + import com.kaltura.recording.business.BaseRecorderParams; + import com.kaltura.recording.business.interfaces.IResponder; + import com.kaltura.recording.controller.events.AddEntryEvent; + import com.kaltura.recording.controller.events.RecorderEvent; + import com.kaltura.vo.KalturaMediaEntry; + + import flash.events.Event; + import flash.events.EventDispatcher; + import flash.events.NetStatusEvent; + import flash.media.Camera; + import flash.media.Microphone; + import flash.media.SoundMixer; + import flash.media.SoundTransform; + import flash.media.Video; + import flash.utils.getTimer; + + import mx.utils.ObjectUtil; + import mx.utils.UIDUtil; + + [Event(name="detectedMicrophone", type="com.kaltura.devicedetection.DeviceDetectionEvent")] + [Event(name="detectedCamera", type="com.kaltura.devicedetection.DeviceDetectionEvent")] + [Event(name="errorMicrophone", type="com.kaltura.devicedetection.DeviceDetectionEvent")] + [Event(name="errorCamera", type="com.kaltura.devicedetection.DeviceDetectionEvent")] + [Event(name="netconnectionConnectClosed", type="com.kaltura.net.streaming.events.ExNetConnectionEvent")] + [Event(name="netconnectionConnectFailed", type="com.kaltura.net.streaming.events.ExNetConnectionEvent")] + [Event(name="netconnectionConnectSuccess", type="com.kaltura.net.streaming.events.ExNetConnectionEvent")] + [Event(name="netconnectionConnectRejected", type="com.kaltura.net.streaming.events.ExNetConnectionEvent")] + [Event(name="netconnectionConnectInvalidapp", type="com.kaltura.net.streaming.events.ExNetConnectionEvent")] + [Event(name="netstreamRecordStart", type="com.kaltura.net.streaming.events.RecordNetStreamEvent")] + [Event(name="netstreamPlayStop", type="com.kaltura.net.streaming.events.RecordNetStreamEvent")] + [Event(name="flushStart", type="com.kaltura.net.streaming.events.FlushStreamEvent")] + [Event(name="flushProgress", type="com.kaltura.net.streaming.events.FlushStreamEvent")] + [Event(name="flushComplete", type="com.kaltura.net.streaming.events.FlushStreamEvent")] + [Event(name="addEntryResult", type="com.kaltura.recording.controller.events.AddEntryEvent")] + [Event(name="addEntryFault", type="com.kaltura.recording.controller.events.AddEntryEvent")] + /** + * KRECORDER - Flash Video and Audio Recording and Contributing Application. + *

Goals: + * 1. Simplified Media Device Detection (Active Camera and Microphone). + * 2. Simplified Media Selection Interface (Functions for manually choosing devices from available devices array). + * 3. Server Connection and Error Handling. + * 4. Video and Audio Recording on Red5, Handling of internal NetStream Events and Errors. + * 5. Preview Mechanism - Live Preview using RTMP (Before addentry). + * 6. Simplified addentry function to Kaltura Network Servers. + * 7. Full JavaScript interaction layer. + * 8. Dispatching of Events by Single Object to simplify Development of Recording Applications.

+ * KRecorder does NOT provide any visual elements beyond a native flash video component attached to the recording NetStream. + * + * @author Zohar Babin + */ + public class KRecordControl extends EventDispatcher implements IResponder, IRecordControl + { + + /** + *partner and application settings. + */ + protected var _initRecorderParameters:BaseRecorderParams; + + /** + * when we need to wait for some operation to start we are connecting. + */ + private var _connecting : Boolean = false; + + private var _timeOutId : uint; + + public function get connecting() : Boolean + { + return _connecting; + } + + public function set connecting( value : Boolean ) : void + { + _connecting = value; + + if(_connecting) + dispatchEvent( new Event( RecorderEvent.CONNECTING, true ) ); + else + dispatchEvent( new Event( RecorderEvent.CONNECTING_FINISH, true ) ); + } + + private var _autoPreview : Boolean = true; + + public function get autoPreview() : Boolean + { + return _autoPreview; + } + + public function set autoPreview( value : Boolean ) : void + { + _autoPreview = value; + } + + + /** + * the initialization recorder partner and application parameters. + */ + public function get initRecorderParameters ():BaseRecorderParams + { + return _initRecorderParameters; + } + public function set initRecorderParameters (recorder_parameters:BaseRecorderParams):void + { + _initRecorderParameters = recorder_parameters; + } + + /** + *monitors the connection status to the RTMP recording server. + */ + public var isConnected:Boolean = false; + + /** + *microphone device. + */ + protected var microphone:Microphone; + /** + *camera device. + */ + protected var camera:Camera; + public var video:Video = new Video (); + /** + * sets the camera to use, and attaches it to the video component. + */ + protected function setCamera (_camera:Camera):void + { + camera = _camera; + video.attachCamera(camera); + } + /** + *connection channel to the streaming server. + */ + protected var netConnection:ExNetConnection; + /** + *stream to record on. + */ + protected var netStream:RecordNetStream; + + protected var _streamUid:String = ""; + /** + *the uid of the stream recorded. + */ + public function get streamUid ():String + { + return _streamUid; + } + + /** + * internal implicit setter to change the published stream uid. + * @param value the new strea uid. + */ + private function setStreamUid (value:String):void + { + _streamUid = value; + dispatchEvent(new RecorderEvent(RecorderEvent.STREAM_ID_CHANGE, _streamUid )); + } + + /** + * the timestamp of when the recording started. + */ + private var _recordStartTime:uint; + + private var _recordedTime:uint; + + private var _bufferTime:Number = 70; + + /** + *the duration of the recording in milliseconds. + */ + public function get recordedTime ():uint + { + return _recordedTime; + } + + private var _waitForBufferFlush : Boolean = false; + private var _firstPreviewPause : Boolean = true; + + /** + *sets camera recording quality. + * @param quality An integer that specifies the required level of picture quality, + * as determined by the amount of compression being applied to each video frame. Acceptable values range from 1 + * (lowest quality, maximum compression) to 100 (highest quality, no compression). + * To specify that picture quality can vary as needed to avoid exceeding bandwidth, pass 0 for quality. + * @param bw Specifies the maximum amount of bandwidth that the current outgoing video feed can use, + * in bytes per second. To specify that Flash Player video can use as much bandwidth as needed to + * maintain the value of quality, pass 0 for bandwidth. The default value is 16384. + * @param w the width of the frame. + * @param h the height of the frame. + * @param fps frame per second to use. + */ + public function setQuality (quality:int, bw:int, w:int, h:int, fps:Number, gop:int=15):void + { + camera.setKeyFrameInterval(gop) + camera.setMode(w, h, fps); + camera.setQuality(bw, quality); + } + + /** + *resize the video display. + * @param w the new width. + * @param h the new height. + */ + public function resizeVideo (w:Number, h:Number):void + { + if (camera) + { + trace ("video: ",w, h); + video = new Video (w, h); + video.width = w; + video.height = h; + video.attachCamera(camera); + } + } + + /** + * an internal implicit setter to recordTime property. + * @param value the new stream recorded length. + */ + protected function setRecordedTime (value:uint):void + { + _recordedTime = value; + dispatchEvent(new RecorderEvent(RecorderEvent.UPDATE_RECORDED_TIME, _recordedTime )); + } + + private var _blackRecordTime:uint = 0; + /** + * this is the blacked out recording time since the client sent request to record and the server sent approve. + * we later cut the stream accordingly. + */ + public function get blackRecordTime():uint + { + return _blackRecordTime; + } + + /** + * an internal implicit setter to the blackRecordTime property. + * @param val the new duration between record command and actual publish start. + */ + protected function setBlackRecordTime(val:uint):void + { + _blackRecordTime = val; + } + + /** + * activity level measured on the microphone. + */ + public function get micophoneActivityLevel ():Number + { + if (microphone) + return microphone.activityLevel; + else + return 0; + } + + /** + * Returns the gain of the microphone + * @return + * + */ + public function get microphoneGain () : Number { + if (microphone) + return microphone.gain; + else + return 0; + } + + public function set microphoneGain(val:Number) : void { + if (microphone) { + microphone.gain = val; + } + + } + + /** + * locate active input devices. + */ + public function deviceDetection ():void + { + + detectMicrophoneDevice (); + } + + /** + * detect the most active microphone device. + */ + protected function detectMicrophoneDevice ():void + { + if (! microphone){ + DeviceDetector.getInstance().addEventListener(DeviceDetectionEvent.DETECTED_MICROPHONE, microphoneDeviceDetected, false, 0, true); + DeviceDetector.getInstance().addEventListener(DeviceDetectionEvent.ERROR_MICROPHONE, microphoneDetectionError, false, 0, true); + DeviceDetector.getInstance().addEventListener(DeviceDetectionEvent.MIC_DENIED, microphoneDenyError, false, 0, true); + DeviceDetector.getInstance().detectMicrophone(); + } else { + detectCameraDevice(); + } + } + /** + * microphone detected. + */ + private function microphoneDeviceDetected (event:DeviceDetectionEvent):void + { + removeMicrophoneDetectionListeners (); + microphone = DeviceDetector.getInstance().microphone; + dispatchEvent(event.clone()); + detectCameraDevice (); + } + /** + * camera deny + */ + private function cameraDenyError (event:DeviceDetectionEvent):void + { + dispatchEvent(event.clone()); + } + + /** + * microphone deny + */ + private function microphoneDenyError (event:DeviceDetectionEvent):void + { + dispatchEvent(event.clone()); + } + /** + * no microphone detected. + */ + private function microphoneDetectionError (event:DeviceDetectionEvent):void + { + removeMicrophoneDetectionListeners (); + dispatchEvent(event.clone()); + detectCameraDevice (); + } + private function removeMicrophoneDetectionListeners ():void + { + DeviceDetector.getInstance().removeEventListener(DeviceDetectionEvent.DETECTED_MICROPHONE, microphoneDeviceDetected); + DeviceDetector.getInstance().removeEventListener(DeviceDetectionEvent.ERROR_MICROPHONE, microphoneDetectionError); + } + /** + * detect the most active camera device. + */ + protected function detectCameraDevice ():void + { + DeviceDetector.getInstance().addEventListener(DeviceDetectionEvent.DETECTED_CAMERA, cameraDeviceDetected, false, 0, true); + DeviceDetector.getInstance().addEventListener(DeviceDetectionEvent.CAMERA_DENIED, cameraDenyError, false, 0, true); + DeviceDetector.getInstance().addEventListener(DeviceDetectionEvent.ERROR_CAMERA, cameraDetectionError, false, 0, true); + if (Global.DETECTION_DELAY != 0){ + DeviceDetector.getInstance().detectCamera(Global.DETECTION_DELAY); + } else { + DeviceDetector.getInstance().detectCamera(); + } + } + /** + * camera detected. + */ + private function cameraDeviceDetected (event:DeviceDetectionEvent):void + { + removeCameraDetectionListeners (); + setCamera (DeviceDetector.getInstance().webCam); + dispatchEvent(event.clone()); + } + /** + * no camera detected. + */ + private function cameraDetectionError (event:DeviceDetectionEvent):void + { + removeCameraDetectionListeners (); + dispatchEvent(event.clone()); + } + private function removeCameraDetectionListeners ():void + { + DeviceDetector.getInstance().removeEventListener(DeviceDetectionEvent.DETECTED_CAMERA, cameraDeviceDetected); + DeviceDetector.getInstance().removeEventListener(DeviceDetectionEvent.ERROR_CAMERA, cameraDetectionError); + } + + /** + * a list of available camera devices on the system. + */ + public function getCameras ():Array + { + return Camera.names; + } + + /** + * manually set the camera device to use. + */ + public function setActiveCamera (camera_name:String):void + { + removeCameraDetectionListeners (); + var i:int; + var found:Boolean = false; + for (i = 0; i < Camera.names.length; ++i) + { + if (camera_name == Camera.names[i]) { + found = true; + break; + } + } + setCamera (Camera.getCamera (found == true ? i.toString() : null)); + } + + /** + * a list of available microphone devices on the system. + */ + public function getMicrophones ():Array + { + return Microphone.names; + } + + /** + * manually select the microphone device to use. + */ + public function setActiveMicrophone (microphone_name:String):void + { + removeMicrophoneDetectionListeners (); + var i:int; + var found:Boolean = false; + for (i = 0; i < Microphone.names.length; ++i) + { + if (microphone_name == Microphone.names[i]) { + found = true; + break; + } + } + microphone = Microphone.getMicrophone (found == true ? i : null); + } + + /** + * start a connection to the streaming server. + */ + public function connectToRecordingServie ():void + { + isConnected = false; + netConnection = new ExNetConnection (); + netConnection.addEventListener(ExNetConnectionEvent.NETCONNECTION_CONNECT_SUCCESS, connectionSuccess, false, 0, true); + netConnection.addEventListener(ExNetConnectionEvent.NETCONNECTION_CONNECT_CLOSED, connectionFailed, false, 0, true); + netConnection.addEventListener(ExNetConnectionEvent.NETCONNECTION_CONNECT_FAILED, connectionFailed, false, 0, true); + netConnection.addEventListener(ExNetConnectionEvent.NETCONNECTION_CONNECT_INVALIDAPP, connectionFailed, false, 0, true); + netConnection.addEventListener(ExNetConnectionEvent.NETCONNECTION_CONNECT_REJECTED, connectionFailed, false, 0, true); + netConnection.addEventListener(NetStatusEvent.NET_STATUS,onNetConnectionStatus); + netConnection.connect(_initRecorderParameters.rtmpHost); + } + /** + * connected to the streaming server successfully. + */ + private function connectionSuccess (event:ExNetConnectionEvent):void + { + openStream (event); + } + /** + * there was an error in connecting the streaming server. + */ + private function connectionFailed (event:ExNetConnectionEvent):void + { + isConnected = false; + trace ("can't connect to streaming server, " + ObjectUtil.toString(event.connectionInfo)); + dispatchEvent(event.clone()); + } + /** + * open a stream to publish on. + */ + protected function openStream (event:ExNetConnectionEvent = null):void + { + if (netStream) + { + + netStream.removeEventListener(FlushStreamEvent.FLUSH_START, streamFlushBubble); + netStream.removeEventListener(FlushStreamEvent.FLUSH_COMPLETE, streamFlushBubble); + netStream.removeEventListener(FlushStreamEvent.FLUSH_PROGRESS, streamFlushBubble); + netStream.removeEventListener(RecordNetStreamEvent.NETSTREAM_RECORD_START, recordStarted); + netStream.removeEventListener(RecordNetStreamEvent.NETSTREAM_PLAY_COMPLETE, stoppedStream); + netStream.removeEventListener(NetStatusEvent.NET_STATUS , onNetStatus ); + } + netStream = new RecordNetStream (netConnection, UIDUtil.createUID(), true, true); + netStream.bufferTime = _bufferTime; + netStream.addEventListener(FlushStreamEvent.FLUSH_START, streamFlushBubble, false, 0, true); + netStream.addEventListener(FlushStreamEvent.FLUSH_COMPLETE, streamFlushBubble, false, 0, true); + netStream.addEventListener(FlushStreamEvent.FLUSH_PROGRESS, streamFlushBubble, false, 0, true); + netStream.addEventListener(RecordNetStreamEvent.NETSTREAM_RECORD_START, recordStarted, false, 0, true); + netStream.addEventListener(RecordNetStreamEvent.NETSTREAM_PLAY_COMPLETE, stoppedStream, false, 0, true); + netStream.addEventListener(NetStatusEvent.NET_STATUS , onNetStatus ); + isConnected = true; + if (event) + dispatchEvent(event.clone()); + } + + /** + * the net connection status report while working. + */ + protected function onNetConnectionStatus( event : NetStatusEvent ) : void + { + trace("NetConnectionStatus: " + event.info.code); + dispatchEvent( event ); + } + + /** + * the stream report on a net status event while working. + */ + protected function onNetStatus( event : NetStatusEvent ) : void + { + trace("NetStatusEvent: " + event.info.code); + + switch(event.info.code) + { + case "NetStream.Play.Start": + if(_firstPreviewPause) + { + pausePreviewRecording(); + + //if(_timeOutId) + //clearTimeout( _timeOutId ); + + //_timeOutId = setTimeout( readyToPreview , 30000 ); + } + + break; + + case "NetStream.Play.Stop": + if(_firstPreviewPause) + { + readyToPreview(); + } + break; + + case "NetStream.Unpause.Notify": + connecting = false; + break; + + case "NetStream.Buffer.Full": + if(_firstPreviewPause) + { + readyToPreview(); + } + break; + } + + dispatchEvent( event ); + } + + private function readyToPreview() : void + { + _firstPreviewPause = false; + resume(); + } + + /** + * the stream is fully flushed and saved on the server. + */ + protected function streamFlushBubble (event:FlushStreamEvent):void + { + trace("streamFlushBubble"); + dispatchEvent(event.clone()); + } + /** + * the server confirmed start recording. + */ + protected function recordStarted (event:RecordNetStreamEvent):void + { + trace("recordStarted"); + connecting = false; + dispatchEvent(event.clone()); + setBlackRecordTime (getTimer() - _recordStartTime); + } + /** + * the stream has endded play (after preview finished). + */ + protected function stoppedStream (event:RecordNetStreamEvent):void + { + trace("stoppedStream"); + _firstPreviewPause = true; + delayedStoppedHandler(event); + } + + private function delayedStoppedHandler (event:RecordNetStreamEvent):void + { + trace("delayedStoppedHandler"); + clearVideoAndSetCamera (); + dispatchEvent(event); + } + + /** + * clear the preview and set camera back + */ + public function clearVideoAndSetCamera ():void + { + trace("clearVideoAndSetCamera"); + video.attachNetStream(null); + openStream (); + setCamera(camera); + } + + /** + * start publishing the audio. + */ + public function recordNewStream ():void + { + if (netStream) + { + setCamera (camera); + if (camera) + netStream.attachCamera(camera); + if (microphone) + netStream.attachAudio(microphone); + setStreamUid (UIDUtil.createUID()); + trace ("publishing: " + _streamUid); + connecting = true; //setting loader until the Record.Start is called + netStream.publish(_streamUid, RecordNetStream.PUBLISH_METHOD_RECORD); + _recordStartTime = getTimer(); + } + } + + /** + * stop publishing to the server. + */ + public function stopRecording ():void + { + setRecordedTime(getTimer() - _recordStartTime); + if (netStream) + netStream.stop(); + } + + /** + * play the recorded stream. + */ + public function previewRecording ():void + { + trace("previewRecording"); + if (netStream) + { + connecting = true; + video.attachNetStream(netStream); + trace("playing: " + _streamUid); + netStream.playMedia(_streamUid); + } + } + + /** + * stop the playing stream. + */ + public function stopPreviewRecording ():void + { + trace("stopPreviewRecording"); + if (netStream) + { + _firstPreviewPause = true; + netStream.stop(); + } + } + + /** + * pause the playing stream. + */ + public function pausePreviewRecording ():void + { + trace("pausePreviewRecording"); + if (netStream) + netStream.pause(); + } + + /** + * seek the playing stream. + */ + public function seek( offset : Number ) : void + { + trace("seek"); + if (netStream) + netStream.seek( offset ); + } + + /** + * resume the playing stream. + */ + public function resume() : void + { + trace("resume"); + if (netStream) + netStream.resume(); + } + + /** + * The position of the playing stream playhead, in seconds. + */ + public function get playheadTime() : Number + { + if (netStream) + return netStream.time; + + return NaN; + } + + /** + * set the recorder netStream bufferTime. + */ + public function set bufferTime( value : Number ) : void + { + _bufferTime = value; + + if (netStream) + netStream.bufferTime = _bufferTime; + } + + /** + * get the recorder netStream bufferLength. + */ + public function get bufferLength() : Number + { + if(netStream) + return netStream.bufferLength; + + return NaN; + } + + + /// + /// + /// + + /** + * add the last recording as a new Kaltura entry in the Kaltura Network. + * @param entry_name the name for the new added entry. + * @param entry_tags user tags for the newly created entry. + * @param entry_description description of the newly created entry. + * @param credits_screen_name for anonymous user applications - the screen name of the user that contributed the entry. + * @param credits_site_url for anonymous user applications - the website url of the user that contributed the entry. + * @param categories categories of entry + * @param admin_tags admin tags for the newly created entry. + * @param license_type the content license type to use (this is arbitrary to be set by the partner). + * @param credit custom partner credit feild, will be used to attribute the contributing source. + * @param group_id used to group multiple entries in a group. + * @param partner_data special custom data for partners to store. + * @see com.kaltura.recording.business.AddEntryDelegate + */ + public function addEntry (entry_name:String, entry_tags:String, entry_description:String, credits_screen_name:String = '', + credits_site_url:String = '', categories:String="", admin_tags:String = '', license_type:String = '', + credit:String = '', group_id:String = '', partner_data:String = ''):void + { + + var kc:KalturaClient = Global.KALTURA_CLIENT; + var entry:KalturaMediaEntry = new KalturaMediaEntry(); + entry.mediaType = 1; + entry.name = entry_name; + entry.tags = entry_tags; + entry.description = entry_description; + entry.creditUserName = credits_screen_name; + if(categories && categories !="") + entry.categories = categories; + entry.creditUrl = credits_site_url; + if(admin_tags && admin_tags !="") + entry.adminTags = admin_tags; + entry.licenseType = int(license_type); + entry.groupId = int(group_id); + entry.partnerData = partner_data; + // + var addEntry:MediaAddFromRecordedWebcam = new MediaAddFromRecordedWebcam(entry,streamUid); + addEntry.useTimeout = false; + addEntry.addEventListener(KalturaEvent.COMPLETE,result); + addEntry.addEventListener(KalturaEvent.FAILED,fault); + kc.post(addEntry); + } + + public function result (data:Object):void + { + trace ("result",ObjectUtil.toString(data)); + dispatchEvent(new AddEntryEvent (AddEntryEvent.ADD_ENTRY_RESULT, data.data)); + } + public function fault (info:Object):void + { + trace ("fault",ObjectUtil.toString(info)); + dispatchEvent(new AddEntryEvent (AddEntryEvent.ADD_ENTRY_FAULT, info)); + } + } +} diff --git a/KalturaRecord/src/com/kaltura/recording/controller/events/AddEntryEvent.as b/KalturaRecord/src/com/kaltura/recording/controller/events/AddEntryEvent.as new file mode 100644 index 0000000..ffb85cb --- /dev/null +++ b/KalturaRecord/src/com/kaltura/recording/controller/events/AddEntryEvent.as @@ -0,0 +1,53 @@ +/* +// =================================================================================================== +// _ __ _ _ +// | |/ /__ _| | |_ _ _ _ _ __ _ +// | ' . +// +// @ignore +// =================================================================================================== +*/ +package com.kaltura.recording.controller.events +{ + import flash.events.Event; + + public class AddEntryEvent extends Event + { + static public const ADD_ENTRY_RESULT:String = "addEntryResult"; + static public const ADD_ENTRY_FAULT:String = "addEntryFault"; + + public var info:Object; + + public function AddEntryEvent(type:String, _info:Object) + { + super(type, true, false); + info = _info; + } + + override public function clone():Event + { + return new AddEntryEvent (type, info); + } + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/com/kaltura/recording/controller/events/RecorderEvent.as b/KalturaRecord/src/com/kaltura/recording/controller/events/RecorderEvent.as new file mode 100644 index 0000000..5e7f88b --- /dev/null +++ b/KalturaRecord/src/com/kaltura/recording/controller/events/RecorderEvent.as @@ -0,0 +1,66 @@ +/* +// =================================================================================================== +// _ __ _ _ +// | |/ /__ _| | |_ _ _ _ _ __ _ +// | ' . +// +// @ignore +// =================================================================================================== +*/ +package com.kaltura.recording.controller.events +{ + import flash.events.Event; + + public class RecorderEvent extends Event + { + public static const CONNECTION_ESTABLISHED:String = "connectionEstablished"; + public static const DEVICE_DETECTED:String = "deviceDetected"; + public static const CONNECTION_ERROR:String = "connectionError"; + public static const DEVICE_ERROR:String = "deviceError"; + + public static const RECORDER_PUBLISH:String = "recorderPublish"; + public static const RECORDER_BUTTON_CLICK:String = "recorderButtonClick"; + public static const RECORDER_FLUSH:String = "recorderFlush"; + public static const RECORDER_PLAY:String = "recorderPlay"; + public static const RECORDER_STOP:String = "recorderStop"; + public static const RECORDER_APPROVE:String = "recorderApprove"; + public static const RECORDER_CANCEL:String = "recorderCancel"; + public static const CONNECTING : String = "connecting"; + public static const CONNECTING_FINISH : String = "connectingFinish"; + public static const STREAM_ID_CHANGE : String = "streamIdChange"; + public static const UPDATE_RECORDED_TIME : String = "updateRecordedTime"; + + public var data:Object; + + public function RecorderEvent (type:String, event_data:Object = null) + { + super(type, true, false); + data = event_data; + } + + override public function clone():Event + { + return new RecorderEvent (type, data); + } + } +} \ No newline at end of file diff --git a/KalturaRecord/src/com/kaltura/recording/view/Button.as b/KalturaRecord/src/com/kaltura/recording/view/Button.as new file mode 100644 index 0000000..15f288f --- /dev/null +++ b/KalturaRecord/src/com/kaltura/recording/view/Button.as @@ -0,0 +1,81 @@ +// TODO: support label + +package com.kaltura.recording.view +{ + +import com.kaltura.utils.KMovieClipUtil; + +import flash.display.MovieClip; +import flash.events.Event; +import flash.events.MouseEvent; +import flash.text.TextField; +import flash.text.TextFieldAutoSize; + + +public class Button extends UIComponent +{ + + private var _label:TextField; + + + public function Button( skin:MovieClip=null ) + { + super( skin ); + + buttonMode = true; + mouseChildren = false; + } + + override protected function onAddedToStage(evt:Event=null):void + { + addEventListener( MouseEvent.MOUSE_OVER, onMouseOver, false, 0, true ); + addEventListener( MouseEvent.MOUSE_OUT, onMouseOut, false, 0, true ); + addEventListener( MouseEvent.CLICK, onMouseClick, false, 0, true ); + } + + override protected function redraw():void + { + super.redraw(); + + _label = _skin["label"]; + if( _label ) _label.autoSize = TextFieldAutoSize.CENTER; + } + + protected function onMouseClick( evt:Event ):void + { +// trace( "CLICK " + this ); + } + + protected function onMouseOver( evt:Event=null ):void + { + if( _state != "over" ) + { + if( KMovieClipUtil.hasLabel( _skin, "over" )) + _skin.gotoAndStop( "over" ); + _state = "over"; + } + } + + protected function onMouseOut( evt:Event=null ):void + { + if( _state != "up" ) + { + if( KMovieClipUtil.hasLabel( _skin, "up" )) + _skin.gotoAndStop( "up" ); + _state = "up"; + } + } + + public function set label( value:String ):void + { + if( _label ) _label.text = value; + } + + override public function setState( state:String ):void + { + if( state == "up" ) onMouseOut(); + if( state == "over" ) onMouseOver(); + } + +} +} \ No newline at end of file diff --git a/KalturaRecord/src/com/kaltura/recording/view/KRecordViewParams.as b/KalturaRecord/src/com/kaltura/recording/view/KRecordViewParams.as new file mode 100644 index 0000000..d666545 --- /dev/null +++ b/KalturaRecord/src/com/kaltura/recording/view/KRecordViewParams.as @@ -0,0 +1,17 @@ +package com.kaltura.recording.view +{ + public class KRecordViewParams + { + public var themeUrl:String; + public var localeUrl:String; + public var autoPreview:Boolean; + + public function KRecordViewParams(themeUrl:String, localeUrl:String, autoPreview:String) + { + this.themeUrl = themeUrl; + this.localeUrl = localeUrl; + this.autoPreview = (autoPreview == '1'); + } + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/com/kaltura/recording/view/PopupDialog.as b/KalturaRecord/src/com/kaltura/recording/view/PopupDialog.as new file mode 100644 index 0000000..2f2c87a --- /dev/null +++ b/KalturaRecord/src/com/kaltura/recording/view/PopupDialog.as @@ -0,0 +1,51 @@ +package com.kaltura.recording.view +{ + +import flash.display.MovieClip; +import flash.text.TextField; + + +public class PopupDialog extends PopupMessage +{ + + public var buttonYes:Button; + public var buttonNo:Button; +// private var _message:TextField; + + + public function PopupDialog( skin:MovieClip ) + { + super( skin ); + } + + override protected function redraw():void + { + super.redraw(); + + buttonYes = new Button( _skin["buttonYes"] ); + buttonYes.name = "buttonYes"; + buttonYes.label = Global.LOCALE.getString( "Button.Yes" ); + _skin.addChild( buttonYes ); + + buttonNo = new Button( _skin["buttonNo"] ); + buttonNo.name = "buttonNo"; + buttonNo.label = Global.LOCALE.getString( "Button.No" ); + _skin.addChild( buttonNo ); + + _message = _skin["message"]; + } + + public function set message( value:String ):void + { + _message.text = value; + } + + override protected function validateSkin( skin:MovieClip ):Boolean + { + if( skin["message"] && skin["buttonYes"] && skin["buttonNo"] ) + return( true ); + else + return( false ); + } +} +} \ No newline at end of file diff --git a/KalturaRecord/src/com/kaltura/recording/view/PopupMessage.as b/KalturaRecord/src/com/kaltura/recording/view/PopupMessage.as new file mode 100644 index 0000000..546cc95 --- /dev/null +++ b/KalturaRecord/src/com/kaltura/recording/view/PopupMessage.as @@ -0,0 +1,42 @@ +package com.kaltura.recording.view +{ + +import flash.display.MovieClip; +import flash.text.TextField; + + +public class PopupMessage extends UIComponent +{ + + protected var _message:TextField; + + + public function PopupMessage( skin:MovieClip ) + { + super( skin ); + } + + override protected function redraw():void + { + super.redraw(); + + _message = _skin["message"] + } + + public function set text( value:String ):void + { + if( _message ) + { + _message.text = value; + } + } + + override protected function validateSkin( skin:MovieClip ):Boolean + { + if( skin["message"] ) + return( true ); + else + return( false ); + } +} +} \ No newline at end of file diff --git a/KalturaRecord/src/com/kaltura/recording/view/PreviewPlayer.as b/KalturaRecord/src/com/kaltura/recording/view/PreviewPlayer.as new file mode 100644 index 0000000..3a02a6b --- /dev/null +++ b/KalturaRecord/src/com/kaltura/recording/view/PreviewPlayer.as @@ -0,0 +1,263 @@ +package com.kaltura.recording.view +{ + + import com.kaltura.net.streaming.events.RecordNetStreamEvent; + + import flash.display.MovieClip; + import flash.display.Sprite; + import flash.events.Event; + import flash.events.MouseEvent; + import flash.events.NetStatusEvent; + import flash.text.TextField; + + + public class PreviewPlayer extends UIComponent + { + + public var buttonSave:Button; + public var buttonReRecord:Button; + public var buttonPlay:Button; + public var buttonPause:Button; + public var buttonStop:Button; + public var progressBar:ProgressBar; + public var textProgress:TextField; + private var _totalTime:Number=0; + private var _autoPreview : Boolean = true; + + public var playheadTime : String; + public static const PREVIEW_UPDATE_PLAYHEAD:String = "previewUpdatePlayhead" + public static const PREVIEW_DONE:String = "previewDone" + public static const PREVIEW_STOPPED:String = "previewStopped" + + public function PreviewPlayer( skin:MovieClip ) + { + super( skin ); + Global.RECORD_CONTROL.addEventListener( NetStatusEvent.NET_STATUS , onNetStatus ); + } + + private function onNetStatus( event : NetStatusEvent ) : void + { + switch(event.info.code) + { + case "NetStream.Unpublish.Success": + if(Global.VIEW_PARAMS.autoPreview==true) + { + stop(); + play(); + Global.RECORD_CONTROL.previewRecording(); //need to add it because play was called without mouse event + } + else{ + Global.RECORD_CONTROL.stopPreviewRecording() + } + break; + } + } + + override protected function redraw():void + { + super.redraw(); + buttonSave = new Button( _skin["buttonSave"] ); + buttonSave.name = "buttonSave"; + if(!Global.REMOVE_PLAYER) + _skin.addChild( buttonSave ); + + buttonReRecord = new Button( _skin["buttonReRecord"] ); + buttonReRecord.name = "buttonReRecord"; + if(!Global.REMOVE_PLAYER) + _skin.addChild( buttonReRecord ); + + buttonPlay = new Button( _skin["buttonPlay"] ); + buttonPlay.addEventListener( MouseEvent.CLICK, onMouseClick, false, 0, true ); + buttonPlay.name = "buttonPlay"; + buttonPlay.visible = true; + if(!Global.REMOVE_PLAYER) + _skin.addChild( buttonPlay ); + + buttonPause = new Button( _skin["buttonPause"] ); + // buttonPause.addEventListener( MouseEvent.CLICK, onMouseClick, false, 0, true ); + buttonPause.name = "buttonPause"; + buttonPause.visible = false; + if(!Global.REMOVE_PLAYER) + _skin.addChild( buttonPause ); + + buttonStop = new Button( _skin["buttonStop"] ); + buttonStop.addEventListener( MouseEvent.CLICK, onMouseClick, false, 0, true ); + buttonStop.name = "buttonStop"; + buttonStop.visible = false; + if(!Global.REMOVE_PLAYER) + _skin.addChild( buttonStop ) + + progressBar = new ProgressBar( _skin["progressBar"] ); + progressBar.addEventListener( MouseEvent.CLICK, onMouseClick, false, 0, true ); + progressBar.name = "progressBar"; + if(!Global.REMOVE_PLAYER) + _skin.addChild( progressBar ); + + textProgress = _skin["textProgress"]; + } + + private function onMouseClick( evt:MouseEvent ):void + { + if( evt.target == buttonPlay ) play( evt ); + if( evt.target == buttonStop ) stop(); + if( evt.target == progressBar ) seek( getSeekSeconds() ); + } + + public function play( evt:MouseEvent = null ):void + { + if( !playing ) + { + buttonPlay.visible = false; + buttonStop.visible = true; + // buttonPause.visible = true; + + if( _state == "pause" ) + { + Global.RECORD_CONTROL.resume(); + } + else + { + this.addEventListener( Event.ENTER_FRAME, onProgress, false, 0, true ); + Global.RECORD_CONTROL.addEventListener( RecordNetStreamEvent.NETSTREAM_PLAY_COMPLETE, onPreviewComplete, false, 0, true ); + + if(evt) //if it is a click do preview (before this preview was called twice + Global.RECORD_CONTROL.previewRecording(); + } + _state = "play"; + } + } + + // p = 0 -> 1 + private function getSeekSeconds():Number + { + var ms:Number = progressBar.getProgress()*Global.RECORD_CONTROL.recordedTime; + var s:Number = Math.floor( ms/1000 ); + + return( s ); + } + + public function seek( offset:Number ):void + { + pause(); + Global.RECORD_CONTROL.seek( offset ); + play(); + } + + public function pause():void + { + if( !paused ) + { + buttonPlay.visible = true; + buttonStop.visible = false; + Global.RECORD_CONTROL.pausePreviewRecording(); + _state = "pause"; + } + } + + public function stop():void + { + if( !stopped ) + { + buttonPlay.visible = true; + buttonStop.visible = false; + this.removeEventListener( Event.ENTER_FRAME, onProgress ); + Global.RECORD_CONTROL.removeEventListener( RecordNetStreamEvent.NETSTREAM_PLAY_COMPLETE, onPreviewComplete ); + Global.RECORD_CONTROL.stopPreviewRecording(); + Global.RECORD_CONTROL.clearVideoAndSetCamera(); + updateProgress( 0 ); + _state = "stop"; + dispatchEvent(new Event(PREVIEW_STOPPED)); + } + } + + private function stopPreview() : void + { + Global.RECORD_CONTROL.stopPreviewRecording(); + } + + public function get playing():Boolean + { + return( _state == "play" ); + } + + public function get paused():Boolean + { + return( _state == "pause" ); + } + + public function get stopped():Boolean + { + return( _state == "stop" ); + } + + private function onProgress( evt:Event ):void + { + updateProgress(); + } + + private function updateProgress( p:Number=-1 ):void + { + playheadTime = "00:00:00"; + + if( p<0 ) + { + p =Global.RECORD_CONTROL.playheadTime*1000/Global.RECORD_CONTROL.recordedTime; + playheadTime = ( formatTime( Global.RECORD_CONTROL.playheadTime*1000 )); + } + + var recordedTime:String = formatTime( Global.RECORD_CONTROL.recordedTime ); + + //trace( "playheadTime: " + Global.RECORD_CONTROL.playheadTime ); + + progressBar.setProgress( p ); + + if( playheadTime <= recordedTime ) + textProgress.text = playheadTime + " / " + recordedTime; + else + trace("playheadTime: " + playheadTime); + + dispatchEvent(new Event(PREVIEW_UPDATE_PLAYHEAD)); + + } + + private function onPreviewComplete( evt:Event ):void + { + stop(); + dispatchEvent(new Event(PREVIEW_DONE)); + } + + private function formatTime( ms:Number ):String + { + var formatted:String; + var sec:Number = Math.floor( ms/1000 ); + var min:Number = Math.floor( sec/60 ); + var hour:Number = Math.floor( min/60 ); + + sec = sec - (min*60); + if(min>=60) + min = min - (hour*60); + + var secString:String = String(sec); + var hourString:String = String(hour); + + var minString:String = String(min); + + secString = (secString.length == 1) ? "0" + secString : secString; + minString = (minString.length == 1) ? "0" + minString : minString; + hourString = (hourString.length == 1) ? "0" + hourString : hourString; + + formatted = hourString+":"+minString + ":" + secString; + + return( formatted ); + } + + override protected function validateSkin( skin:MovieClip ):Boolean + { + if( skin["buttonSave"] && skin["buttonReRecord"] && skin["buttonPlay"] && skin["textProgress"] && skin["progressBar"] ) + // if( skin["buttonSave"] && skin["buttonReRecord"] && skin["buttonPlay"] && skin["buttonStop"] ) + return( true ); + else + return( false ); + } + } +} \ No newline at end of file diff --git a/KalturaRecord/src/com/kaltura/recording/view/PreviewTimer.as b/KalturaRecord/src/com/kaltura/recording/view/PreviewTimer.as new file mode 100644 index 0000000..d28d653 --- /dev/null +++ b/KalturaRecord/src/com/kaltura/recording/view/PreviewTimer.as @@ -0,0 +1,20 @@ +package com.kaltura.recording.view +{ + import flash.display.MovieClip; + import flash.text.TextField; + + public class PreviewTimer extends UIComponent + { + private var _time:TextField; + + public function PreviewTimer(s:MovieClip=null) + { + super(s); + _time = _skin["time"]; + } + public function get timer():TextField + { + return _time; + } + } +} \ No newline at end of file diff --git a/KalturaRecord/src/com/kaltura/recording/view/ProgressBar.as b/KalturaRecord/src/com/kaltura/recording/view/ProgressBar.as new file mode 100644 index 0000000..184f2c2 --- /dev/null +++ b/KalturaRecord/src/com/kaltura/recording/view/ProgressBar.as @@ -0,0 +1,77 @@ +package com.kaltura.recording.view +{ + +import flash.display.MovieClip; +import flash.display.Sprite; +import flash.events.MouseEvent; + + +public class ProgressBar extends UIComponent +{ + + private var _progressBar:MovieClip; + private var _hitArea:Sprite; + + private var _progress:Number = 0; + private var _totalWidth:Number; + + + public function ProgressBar( skin:MovieClip=null ) + { + super( skin ); + + buttonMode = true; + mouseChildren = false; + } + + override protected function redraw():void + { + super.redraw(); + + _progressBar = _skin["bar"]; + _progressBar.mouseEnabled = false; + _totalWidth = _progressBar.width; + + _hitArea = new Sprite; + _hitArea.graphics.beginFill( 0xff0000, 0 ); + _hitArea.graphics.drawRect( 0,0,_progressBar.width, _progressBar.height ); + _hitArea.graphics.endFill(); + _hitArea.x = _progressBar.x; + _hitArea.y = _progressBar.y; + _hitArea.buttonMode = true; + _skin.addChildAt( _hitArea, 0 ); + + addEventListener( MouseEvent.CLICK, onMouseClick, false, 0, true ); + } + + private function onMouseClick( evt:MouseEvent ):void + { + var p:Number = _hitArea.mouseX/(_hitArea.width-_hitArea.x); + setProgress( p ); + } + + // value = 0 -> 1 + public function setProgress( p:Number ):void + { + if( _progressBar && p >=0 && p <=1 ) + { + _progressBar.width = _totalWidth*p; + _progress = p; + } + } + + public function getProgress():Number + { + return( _progress ); + } + + override protected function validateSkin( skin:MovieClip ):Boolean + { + if( skin["bar"] ) + return( true ); + else + return( false ); + } + +} +} \ No newline at end of file diff --git a/KalturaRecord/src/com/kaltura/recording/view/ProgressBarRecording.as b/KalturaRecord/src/com/kaltura/recording/view/ProgressBarRecording.as new file mode 100644 index 0000000..9398401 --- /dev/null +++ b/KalturaRecord/src/com/kaltura/recording/view/ProgressBarRecording.as @@ -0,0 +1,70 @@ +package com.kaltura.recording.view +{ + +import flash.display.MovieClip; +import flash.text.TextField; + + +public class ProgressBarRecording extends UIComponent +{ + + private var _time:TextField; + + + public function ProgressBarRecording( skin:MovieClip ) + { + super( skin ); + } + + override protected function redraw():void + { + super.redraw(); + + _time = _skin["time"]; + } + + private function formatTime( ms:Number ):String + { + var formatted:String; + var sec:Number = Math.floor( ms/1000 ); + var min:Number = Math.floor( sec/60 ); + var hour:Number = Math.floor( min/60 ); + + sec = sec - (min*60); + if(min>=60) + min = min - (hour*60); + + var secString:String = String(sec); + var hourString:String = String(hour); + + var minString:String = String(min); + + secString = (secString.length == 1) ? "0" + secString : secString; + minString = (minString.length == 1) ? "0" + minString : minString; + hourString = (hourString.length == 1) ? "0" + hourString : hourString; + + formatted = hourString+":"+minString + ":" + secString; + + return( formatted ); + } + + // value in ms + public function set time( value:Number ):void + { + if( _time ) + { + //TODO + _time.text = formatTime( value ); + } + } + + override protected function validateSkin( skin:MovieClip ):Boolean + { +// if( skin["time"] && skin["soundLevel"] ) + if( skin["time"] ) + return( true ); + else + return( false ); + } +} +} \ No newline at end of file diff --git a/KalturaRecord/src/com/kaltura/recording/view/Theme.as b/KalturaRecord/src/com/kaltura/recording/view/Theme.as new file mode 100644 index 0000000..70ff4fb --- /dev/null +++ b/KalturaRecord/src/com/kaltura/recording/view/Theme.as @@ -0,0 +1,29 @@ +package com.kaltura.recording.view +{ + import flash.display.DisplayObjectContainer; + import flash.display.MovieClip; + + public class Theme + { + private var _container:DisplayObjectContainer; + + public function Theme(container:DisplayObjectContainer) + { + _container = container; + } + + public function getSkinById(id:String):MovieClip + { + var mc:MovieClip = _container.getChildByName(id) as MovieClip; + + if ( mc ) + { + mc.x = 0; + mc.y = 0; + } + + return mc; + } + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/com/kaltura/recording/view/UIComponent.as b/KalturaRecord/src/com/kaltura/recording/view/UIComponent.as new file mode 100644 index 0000000..4ac0505 --- /dev/null +++ b/KalturaRecord/src/com/kaltura/recording/view/UIComponent.as @@ -0,0 +1,54 @@ +package com.kaltura.recording.view +{ + +import flash.display.MovieClip; +import flash.display.Sprite; +import flash.events.Event; + + +public class UIComponent extends Sprite +{ + + protected var _skin:MovieClip; + protected var _state:String = "up"; + public static var visibleSkin:Boolean=true + + public function UIComponent( s:MovieClip=null ) + { + this.skin = s; + s.visible=visibleSkin + this.addEventListener( Event.ADDED_TO_STAGE, onAddedToStage, false, 0, true ); + } + + protected function onAddedToStage( evt:Event=null ):void + { + this.removeEventListener( Event.ADDED_TO_STAGE, onAddedToStage ); + } + + public function set skin( value:MovieClip ):void + { + if( validateSkin( value )) + _skin = value; + else + throw new ViewEvent( ViewEvent.INVALID_SKIN, true ); + + redraw(); + } + + protected function validateSkin( skin:MovieClip ):Boolean + { + return( true ); + } + + public function setState( state:String ):void {} + + protected function redraw():void + { + while( numChildren != 0 ) + removeChildAt( 0 ); + + addChild( _skin ); + } + +} +} \ No newline at end of file diff --git a/KalturaRecord/src/com/kaltura/recording/view/View.as b/KalturaRecord/src/com/kaltura/recording/view/View.as new file mode 100644 index 0000000..6bca390 --- /dev/null +++ b/KalturaRecord/src/com/kaltura/recording/view/View.as @@ -0,0 +1,172 @@ +package com.kaltura.recording.view +{ + +import flash.display.DisplayObjectContainer; +import flash.display.Loader; +import flash.display.Sprite; +import flash.events.Event; +import flash.events.IOErrorEvent; +import flash.net.URLLoader; +import flash.net.URLRequest; +import flash.system.ApplicationDomain; +import flash.system.LoaderContext; +import flash.text.TextField; +import flash.text.TextFormat; + + +public class View extends Sprite +{ + public var viewWidth:Number = 320; + public var viewHeight:Number = 240; + + static public var BG:Sprite; + + private var _bg:Sprite = new Sprite; + + private var _states:Object = new Object; + private var _currentState:ViewState; + + private var _message:TextField; + + private var _themeLoader:Loader = new Loader; + private var _localeLoader:URLLoader = new URLLoader; + + function View() + { + addEventListener( Event.ADDED_TO_STAGE, onAddedToStage, false, 0, true ); + } + + private function onAddedToStage( evt:Event=null ):void + { + removeEventListener( Event.ADDED_TO_STAGE, onAddedToStage ); + loadTheme(); + } + + private function loadTheme ():void + { + trace( 'loading theme:', Global.VIEW_PARAMS.themeUrl ) + _themeLoader.contentLoaderInfo.addEventListener( Event.COMPLETE, onLoadThemeComplete ); + _themeLoader.contentLoaderInfo.addEventListener( IOErrorEvent.IO_ERROR, onIOError ); + _themeLoader.load( new URLRequest( Global.VIEW_PARAMS.themeUrl +"?r=1" ), new LoaderContext( true, ApplicationDomain.currentDomain )); + } + + private function loadLocale ():void + { + // First create defaults: + Global.LOCALE = new KRecordLocaleDefault (); + + trace( 'loading locale:', Global.VIEW_PARAMS.localeUrl ); + _localeLoader.addEventListener( Event.COMPLETE, onLoadLocaleComplete ); + _localeLoader.addEventListener( IOErrorEvent.IO_ERROR, onIOError ); + _localeLoader.load( new URLRequest( Global.VIEW_PARAMS.localeUrl )); + } + + private function ready ():void + { + addState( "start", new ViewStateStart ); + addState( "recording", new ViewStateRecording ); + addState( "preview", new ViewStatePreview ); + addState( "message", new ViewStateMessage ); + addState( "error", new ViewStateError ); + + parent.addEventListener( Event.RESIZE, onResize, false, 0, true ); + onResize(); + + dispatchEvent( new ViewEvent( ViewEvent.VIEW_READY )); + } + + private function onResize( evt:Event=null ):void + { + for each( var state:ViewState in _states ) + { + state.width = viewWidth; + state.height = viewHeight; + } + } + + private function addState( name:String, state:ViewState ):void + { + _states[ name ] = state; + state.visible = false; + addChild( state ); + } + + public function setState( name:String ):void + { + if( _currentState ) + _currentState.close(); + + _currentState = _states[ name ]; + _currentState.open(); + } + public function getState():* + { + if( _currentState ) + return _currentState; + } + + public function showPopupMessage( message:String ):void + { + ViewStateMessage( _states["message"] ).message = message; + setState( "message" ); + } + + public function showPopupError( message:String ):void + { + ViewStateError( _states["error"] ).message = message; + setState( "error" ); + } + + private function onLoadThemeComplete( evt:Event ):void + { + trace( 'Theme file loaded' ); + Global.THEME = new Theme( _themeLoader.content as DisplayObjectContainer ); + + loadLocale(); + } + + private function onLoadLocaleComplete ( evt:Event ):void + { + trace( 'Locale file loaded' ); + + try + { + Global.LOCALE.load( new XML( _localeLoader.data )); + } + catch (e:Error) + { + trace( 'Error parsing Locale file. Using defaults' ); + } + + ready (); + } + + private function onIOError ( evt:IOErrorEvent ):void + { + trace( evt.text ); + if (evt.target == _localeLoader) + { + trace( "Locale file didn't load. Using defaults" ); + ready (); + } + } + + + ///////////////// + public function setError(value:String):void + { + _message = new TextField() + _message.width = this.width; + _message.height = this.height; + var tf:TextFormat = new TextFormat(); + tf.color = 0xFFFF00; + _message.text = value; + _message.setTextFormat(tf); + addChild(_message); + } + + + + +} +} \ No newline at end of file diff --git a/KalturaRecord/src/com/kaltura/recording/view/ViewEvent.as b/KalturaRecord/src/com/kaltura/recording/view/ViewEvent.as new file mode 100644 index 0000000..7513656 --- /dev/null +++ b/KalturaRecord/src/com/kaltura/recording/view/ViewEvent.as @@ -0,0 +1,29 @@ +package com.kaltura.recording.view +{ + +import flash.events.Event; + + +public class ViewEvent extends Event +{ + + static public const VIEW_READY:String = "viewReady"; + + static public const INVALID_SKIN:String = "invalidSkin"; + + static public const RECORD_START:String = "recordStart"; + static public const RECORD_STOP:String = "recordStop"; + + static public const PREVIEW_SAVE:String = "previewSave"; + static public const PREVIEW_RERECORD:String = "previewReRecord"; + + public var data:*; + + + public function ViewEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false) + { + super(type, bubbles, cancelable); + } + +} +} \ No newline at end of file diff --git a/KalturaRecord/src/com/kaltura/recording/view/ViewState.as b/KalturaRecord/src/com/kaltura/recording/view/ViewState.as new file mode 100644 index 0000000..70012aa --- /dev/null +++ b/KalturaRecord/src/com/kaltura/recording/view/ViewState.as @@ -0,0 +1,68 @@ +package com.kaltura.recording.view +{ + +import flash.display.Sprite; +import flash.events.Event; + +import gs.TweenLite; + + +public class ViewState extends Sprite +{ + + protected var _bg:Sprite = new Sprite; + + + public function ViewState() + { + _bg.graphics.beginFill( 0x0000ff, 0 ); + _bg.graphics.drawRect( 0,0,1,1 ); + _bg.graphics.endFill(); + _bg.visible = false; + addChild( _bg ); + + addEventListener( Event.ADDED_TO_STAGE, onAddedToStage, false, 0, true ); + } + + public function open():void + { + this.alpha = 0; + this.visible = true; + TweenLite.to( this, 0.5, {alpha:1} ); + } + + public function close():void + { + this.alpha = 1; + this.visible = false; + TweenLite.to( this, 0.5, {alpha:0} ); + } + + protected function onAddedToStage( evt:Event=null ):void {} + + override public function set width( value:Number ):void + { + _bg.width = value; + onResize(); + } + + override public function get width():Number + { + return( _bg.width ); + } + + override public function set height( value:Number ):void + { + _bg.height = value; + onResize(); + } + + override public function get height():Number + { + return( _bg.height ); + } + + protected function onResize():void {} + +} +} \ No newline at end of file diff --git a/KalturaRecord/src/com/kaltura/recording/view/ViewStateError.as b/KalturaRecord/src/com/kaltura/recording/view/ViewStateError.as new file mode 100644 index 0000000..5bbfb43 --- /dev/null +++ b/KalturaRecord/src/com/kaltura/recording/view/ViewStateError.as @@ -0,0 +1,31 @@ +package com.kaltura.recording.view +{ + + +public class ViewStateError extends ViewState +{ + + public var _popup:PopupMessage = new PopupMessage( Global.THEME.getSkinById( "popupMessageError" )); + + + public function ViewStateError() + { + addChild( _popup ); + } + + override protected function onResize():void + { + _popup.x = Math.round( this.width/2 ); + _popup.y = Math.round( this.height/2 ); + } + + public function set message( value:String ):void + { + if( _popup ) + { + _popup.text = value; + } + } + +} +} \ No newline at end of file diff --git a/KalturaRecord/src/com/kaltura/recording/view/ViewStateMessage.as b/KalturaRecord/src/com/kaltura/recording/view/ViewStateMessage.as new file mode 100644 index 0000000..e6ab56d --- /dev/null +++ b/KalturaRecord/src/com/kaltura/recording/view/ViewStateMessage.as @@ -0,0 +1,32 @@ +// TODO: cancel popup message as state and add it as a feature in ViewState +package com.kaltura.recording.view +{ + + +public class ViewStateMessage extends ViewState +{ + + public var _popup:PopupMessage = new PopupMessage( Global.THEME.getSkinById( "popupMessageWaiting" )); + + + public function ViewStateMessage() + { + addChild( _popup ); + } + + override protected function onResize():void + { + _popup.x = Math.round( this.width/2 ); + _popup.y = Math.round( this.height/2 ); + } + + public function set message( value:String ):void + { + if( _popup ) + { + _popup.text = value; + } + } + +} +} \ No newline at end of file diff --git a/KalturaRecord/src/com/kaltura/recording/view/ViewStatePreview.as b/KalturaRecord/src/com/kaltura/recording/view/ViewStatePreview.as new file mode 100644 index 0000000..431bedc --- /dev/null +++ b/KalturaRecord/src/com/kaltura/recording/view/ViewStatePreview.as @@ -0,0 +1,110 @@ +package com.kaltura.recording.view +{ + +import flash.events.Event; +import flash.events.MouseEvent; +import flash.text.TextField; + + +public class ViewStatePreview extends ViewState +{ + + static private const MARGIN_BOTTOM:Number = 11; + + public var player:PreviewPlayer = new PreviewPlayer( Global.THEME.getSkinById( "previewPlayer" )); + public var popupDialog:PopupDialog = new PopupDialog( Global.THEME.getSkinById( "popupDialog" )); + public var previewTimer:PreviewTimer; + + public var cornerTextProgress:TextField; + + public function ViewStatePreview() + { + addChild( player ); + addChild( popupDialog ); + + if(Global.SHOW_PREVIEW_TIMER && Global.THEME.getSkinById("playerTimer")) + { + previewTimer = new PreviewTimer( Global.THEME.getSkinById("playerTimer")); + addChild( previewTimer ); + previewTimer.visible = false; + player.addEventListener(PreviewPlayer.PREVIEW_UPDATE_PLAYHEAD,onUpdatePlayhead); + } + player.addEventListener(PreviewPlayer.PREVIEW_DONE, hideTimer); + player.addEventListener(PreviewPlayer.PREVIEW_STOPPED, hideTimer); + + + } + protected function hideTimer( evt:Event=null ):void + { + if(previewTimer) + previewTimer.visible = false; + } + protected function onUpdatePlayhead( evt:Event=null ):void + { + previewTimer.visible = true; + previewTimer.timer.text = player.playheadTime; + } + + override protected function onAddedToStage( evt:Event=null ):void + { + popupDialog.addEventListener( MouseEvent.CLICK, onMouseClick, false, 0, true ); + popupDialog.message = Global.LOCALE.getString( "Dialog.Overwrite" ); + popupDialog.visible = false; + + player.addEventListener( MouseEvent.CLICK, onMouseClick, false, 0, true ); + player.buttonSave.label = Global.LOCALE.getString( "Button.Save" ); + } + + override public function open():void + { + if(previewTimer) + previewTimer.visible = false; + super.open(); + } + + override public function close():void + { + super.close(); + } + + private function onMouseClick( evt:MouseEvent ):void + { + if( evt.target == player.buttonReRecord ) + { + player.stop(); + player.mouseChildren = false; + player.mouseEnabled = false; + popupDialog.visible = true; + } + + if( evt.target == popupDialog.buttonYes || evt.target == popupDialog.buttonNo ) + { + player.mouseChildren = true; + player.mouseEnabled = true; + popupDialog.visible = false; + } + + if( evt.target == popupDialog.buttonYes ) + { + dispatchEvent( new ViewEvent( ViewEvent.PREVIEW_RERECORD, true )); + } + + if( evt.target == player.buttonSave ) + { + player.stop(); + dispatchEvent( new ViewEvent( ViewEvent.PREVIEW_SAVE, true )); + } + } + + override protected function onResize():void + { + player.x = Math.round( this.width/2 ); + player.y = Math.round( this.height - player.height/2 - MARGIN_BOTTOM ); + + popupDialog.x = Math.round( this.width/2 ); + popupDialog.y = Math.round( this.height/2 ); + } + + +} +} \ No newline at end of file diff --git a/KalturaRecord/src/com/kaltura/recording/view/ViewStateRecording.as b/KalturaRecord/src/com/kaltura/recording/view/ViewStateRecording.as new file mode 100644 index 0000000..e8144a8 --- /dev/null +++ b/KalturaRecord/src/com/kaltura/recording/view/ViewStateRecording.as @@ -0,0 +1,124 @@ +package com.kaltura.recording.view +{ + +import flash.events.Event; +import flash.events.MouseEvent; +import flash.events.TimerEvent; +import flash.utils.Timer; +import flash.utils.getTimer; + +import gs.TweenLite; + + +public class ViewStateRecording extends ViewState +{ + + public var buttonStop:Button = new Button( Global.THEME.getSkinById( "buttonStopRecord" )); + public var progressBar:ProgressBarRecording = new ProgressBarRecording( Global.THEME.getSkinById( "recordingProgressBar" )); + + private var _hideTimer:Timer = new Timer( 500, 1 ); + private var _recordingTimer:Timer; + private var _recordingStartTime:int; + + public function ViewStateRecording() + { + _bg.visible = true; + _bg.buttonMode = true; + + buttonStop.mouseEnabled = false; + buttonStop.label = Global.LOCALE.getString( "Button.StopRecord" ); + + addChild( buttonStop ); + addChild( progressBar ); + + _hideTimer = new Timer( 2000, 1 ); + _hideTimer.addEventListener( TimerEvent.TIMER, onHideTimer, false, 0, true ); + + _recordingTimer = new Timer( 1000 ); + _recordingTimer.addEventListener( TimerEvent.TIMER, onRecordingTimer, false, 0, true ); + + } + + override protected function onResize():void + { + buttonStop.x = Math.round( this.width/2 ); + buttonStop.y = Math.round( this.height/2 ); + + progressBar.x = Math.round( 7 + progressBar.width/2 ); + progressBar.y = Math.round( 7 + progressBar.height/2 ); + } + + override protected function onAddedToStage( evt:Event=null ):void + { + _bg.addEventListener( MouseEvent.MOUSE_OVER, onMouseOver, false, 0, true ); + _bg.addEventListener( MouseEvent.MOUSE_MOVE, onMouseMove, false, 0, true ); + // click on video to stop recording + if(!Global.DISABLE_GLOBAL_CLICK) + this.addEventListener( MouseEvent.CLICK, onMouseClick, false, 0, true ); + //stage.addEventListener( Event.MOUSE_LEAVE, onMouseOut, false, 0, true ); + root.addEventListener( Event.MOUSE_LEAVE, onMouseOut, false, 0, true ); + } + + override public function open():void + { + super.open(); + _hideTimer.start(); + + progressBar.time = 0; + _recordingStartTime = getTimer(); + _recordingTimer.start(); + } + + override public function close():void + { + super.close(); + _hideTimer.reset(); + _recordingTimer.reset(); + } + + private function onMouseOut( evt:Event ):void + { + buttonStop.setState( "up" ); + } + + private function onMouseOver( evt:MouseEvent ):void + { + buttonStop.setState( "over" ); + } + + private function onMouseClick( evt:Event ):void + { + evt.stopImmediatePropagation(); + evt = new ViewEvent( ViewEvent.RECORD_STOP, true ); + dispatchEvent( evt ); + } + + private function onMouseMove( evt:MouseEvent ):void + { + showButton(); + _hideTimer.reset(); + _hideTimer.start(); + } + + private function onHideTimer( evt:TimerEvent ):void + { + hideButton(); + } + + private function onRecordingTimer (evt:TimerEvent):void + { + progressBar.time = getTimer() - _recordingStartTime; + } + + private function showButton():void + { + TweenLite.to( buttonStop, 0.5, {alpha:1} ); + } + + private function hideButton():void + { + TweenLite.to( buttonStop, 0.5, {alpha:0} ); + } + +} +} \ No newline at end of file diff --git a/KalturaRecord/src/com/kaltura/recording/view/ViewStateSaving.as b/KalturaRecord/src/com/kaltura/recording/view/ViewStateSaving.as new file mode 100644 index 0000000..58a084c --- /dev/null +++ b/KalturaRecord/src/com/kaltura/recording/view/ViewStateSaving.as @@ -0,0 +1,32 @@ +package com.kaltura.recording.view +{ + + +public class ViewStateSaving extends ViewState +{ + + public var _popup:PopupMessage = new PopupMessage( Global.THEME.getSkinById( "popupProgress" )); + + + public function ViewStateSaving() + { + addChild( _popup ); + message = "Saving..."; + } + + override protected function onResize():void + { + _popup.x = Math.round( this.width/2 ); + _popup.y = Math.round( this.height/2 ); + } + + public function set message( value:String ):void + { + if( _popup ) + { + _popup.text = value; + } + } + +} +} \ No newline at end of file diff --git a/KalturaRecord/src/com/kaltura/recording/view/ViewStateStart.as b/KalturaRecord/src/com/kaltura/recording/view/ViewStateStart.as new file mode 100644 index 0000000..aea584f --- /dev/null +++ b/KalturaRecord/src/com/kaltura/recording/view/ViewStateStart.as @@ -0,0 +1,60 @@ +package com.kaltura.recording.view +{ + +import flash.events.Event; +import flash.events.MouseEvent; + + +public class ViewStateStart extends ViewState +{ + + public var buttonStart:Button = new Button( Global.THEME.getSkinById( "buttonStartRecord" )); + + + public function ViewStateStart() + { + _bg.visible = true; + if(!Global.DISABLE_GLOBAL_CLICK) + _bg.buttonMode = true; + buttonStart.mouseEnabled = false; + buttonStart.label = Global.LOCALE.getString( "Button.StartRecord" ); + addChild( buttonStart ); + } + + override protected function onResize():void + { + buttonStart.x = Math.round( this.width/2 ); + buttonStart.y = Math.round( this.height/2 ); + } + + override protected function onAddedToStage( evt:Event=null ):void + { + _bg.addEventListener( MouseEvent.MOUSE_OVER, onMouseOver, false, 0, true ); + // add click for start record to the video + if(!Global.DISABLE_GLOBAL_CLICK) + this.addEventListener( MouseEvent.CLICK, onMouseClick, false, 0, true ); + //stage.addEventListener( Event.MOUSE_LEAVE, onMouseOut, false, 0, true ); + root.addEventListener( Event.MOUSE_LEAVE, onMouseOut, false, 0, true ); + } + + private function onMouseOut( evt:Event ):void + { + buttonStart.setState( "up" ); + } + + private function onMouseOver( evt:MouseEvent ):void + { + buttonStart.setState( "over" ); + } + + private function onMouseClick( evt:Event ):void + { + if(evt) + evt.stopImmediatePropagation(); + evt = new ViewEvent( ViewEvent.RECORD_START, true ); + dispatchEvent( evt ); + } + + +} +} \ No newline at end of file diff --git a/KalturaRecord/src/com/kaltura/utils/Config.as b/KalturaRecord/src/com/kaltura/utils/Config.as new file mode 100644 index 0000000..c8722a6 --- /dev/null +++ b/KalturaRecord/src/com/kaltura/utils/Config.as @@ -0,0 +1,135 @@ +/** + * Config. + * + * Notice: Value keys are case sensitive. + * + * @author Dani X Bacon <( Oink ) + * @version 0.2 + */ +package com.kaltura.utils { + + import flash.utils.Dictionary; + + public class Config { + + private var _data:Dictionary; + //private var isIgnoreCase:Boolean = true; + + function Config(data:XML = null) { + + this._data = new Dictionary(); + if (data) load(data); + + } + + /** + * Loads from xml key/value pairs settings into config. + * + * Expected xml schema: + * + * + * string + * any value + * + * + * string + * any value + * + * + * + * Load ignores any tags other than which are directly under xml root. + */ + public function load(data:XML):void { + + var count:int = 0; + + for each (var setting:XML in data.setting) { + + count++; + var key:String = setting.key; + if (!key) trace ("XML Format error"); + setKey(key, setting.value); + + } + + } + + public function contains(key:String):Boolean { + + return (this._data[key] != undefined); + + } + + public function get( key:String ):* { + + if ( this.contains( key ) ) + return ( this._data[key] ); + else + trace( "Undefined key:", key ); + + } + + public function getBoolean(key:String):Boolean { + + var value:String = get( key ); + + value.toLowerCase(); + if ( value == "true" || value == "yes" || value == "1" ) return true; + if ( value == "false" || value == "no" || value == "0" ) return false; + trace( "Value is not a Boolean", key ); + return false; + } + + public function getNumber(key:String):Number { + + if (isNaN(get(key))) trace( "Value is not a Number", key ); + var value:Number = Number(get(key)); + return value; + + } + + public function getString(key:String):String { + + var value:String = String( get( key ) ); + return (value); + + } + + public function getConfig(key:String):Config { + + var value:Config = new Config(get(key)); + return value; + + } + + public function setKey(key:String, value:*):void { + + this._data[key] = value; + + } + + /* + public function set ignoreCase(isIgnore:Boolean):void {} + + public function get ignoreCase():Boolean { + + return new Boolean(); + + } + */ + + public function toExtendedString():String { + + var str:String = new String(); + for (var key:String in this._data) { + + str += (key + " = " + this._data[key] + "\n"); + + } + return str; + + } + + } + +} \ No newline at end of file diff --git a/KalturaRecord/src/com/kaltura/utils/KMovieClipUtil.as b/KalturaRecord/src/com/kaltura/utils/KMovieClipUtil.as new file mode 100644 index 0000000..6b23935 --- /dev/null +++ b/KalturaRecord/src/com/kaltura/utils/KMovieClipUtil.as @@ -0,0 +1,20 @@ +package com.kaltura.utils +{ + +import flash.display.MovieClip; + + +public class KMovieClipUtil +{ + + static public function hasLabel( mc:MovieClip, label:String ):Boolean + { + for( var i:Number=0; i -1; i--) { + tween = $targetTweens[i]; + if (tween == $tween) { + index = i; + } else if (i < index && tween.startTime <= startTime && tween.startTime + (tween.duration * 1000 / tween.combinedTimeScale) > startTime) { + a[a.length] = tween; + } + } + if (a.length == 0 || $tween.tweens.length == 0) { + return; + } + if (m == AUTO) { + var tweens:Array = $tween.tweens, v:Object = {}, j:int, ti:TweenInfo, overwriteProps:Array; + for (i = tweens.length - 1; i > -1; i--) { + ti = tweens[i]; + if (ti.isPlugin) { //is a plugin with multiple overwritable properties + if (ti.name == "_MULTIPLE_") { + overwriteProps = ti.target.overwriteProps; + for (j = overwriteProps.length - 1; j > -1; j--) { + v[overwriteProps[j]] = true; + } + } else { + v[ti.name] = true; + } + v[ti.target.propName] = true; + } else { + v[ti.name] = true; + } + } + + for (i = a.length - 1; i > -1; i--) { + killVars(v, a[i].exposedVars, a[i].tweens); + } + } else { + for (i = a.length - 1; i > -1; i--) { + a[i].enabled = false; //flags for garbage collection + } + } + } + + public static function killVars($killVars:Object, $vars:Object, $tweens:Array):void { + var i:int, p:String, ti:TweenInfo; + for (i = $tweens.length - 1; i > -1; i--) { + ti = $tweens[i]; + if (ti.name in $killVars) { + $tweens.splice(i, 1); + } else if (ti.isPlugin && ti.name == "_MULTIPLE_") { //is a plugin with multiple overwritable properties + ti.target.killProps($killVars); + if (ti.target.overwriteProps.length == 0) { + $tweens.splice(i, 1); + } + } + } + for (p in $killVars) { + delete $vars[p]; + } + } + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/TweenGroup.as b/KalturaRecord/src/gs/TweenGroup.as new file mode 100644 index 0000000..fcb1fc9 --- /dev/null +++ b/KalturaRecord/src/gs/TweenGroup.as @@ -0,0 +1,1047 @@ +/* +VERSION: 1.1 +DATE: 3/31/2009 +ACTIONSCRIPT VERSION: 3.0 (AS2 version is also available) +UPDATES & MORE DETAILED DOCUMENTATION AT: http://blog.greensock.com/tweengroup/ +DESCRIPTION: + TweenGroup is a very powerful, flexible tool for managing groups of TweenLite/TweenMax tweens. + Here are a few of the features: + + - pause(), resume(), reverse(), or restart() the group as a whole. This is an easy way to add + these capabilities to TweenLite instances without the extra Kb of TweenMax! + + - Treat a TweenGroup instance just like an Array, so you can push(), splice(), unshift(), pop(), + slice(), shift(), loop through the elements, access them directly like myGroup[1], and set them directly + like myGroup[2] = new TweenLite(mc, 1, {x:300}) and it'll automatically adjust the timing + of the tweens in the group to honor the alignment and staggering effects you set with + the "align" and "stagger" properties (more on that next...) + + - Easily set the alignment of the tweens inside the group, like: + - myGroup.align = TweenGroup.ALIGN_SEQUENCE; //stacks them end-to-end, one after the other + - myGroup.align = TweenGroup.ALIGN_START; //tweens will start at the same time + - myGroup.align = TweenGroup.ALIGN_END; //tweens will end at the same time + - myGroup.align = TweenGroup.ALIGN_INIT; //same as ALIGN_START except that it honors any delay set in each tween. + - myGroup.align = TweenGroup.ALIGN_NONE; //no special alignment + + - Stagger aligned tweens by a set amount of time (in seconds). For example, if the stagger value is 0.5 and + the align property is set to ALIGN_START, the second tween will start 0.5 seconds after the first one starts, + then 0.5 seconds later the third one will start, etc. If the align property is ALIGN_SEQUENCE, there would + be 0.5 seconds added between each tween. + + - Have precise control over the progress of the group by getting/setting the "progress" property anytime. + For example, to skip to half-way through the entire group of tweens, simply do this: + myGroup.progress = 0.5 + You can even tween the progress property with another tween to fastforward/rewind an entire group! + + - Call any function when the TweenGroup completes using the onComplete property, and pass any number of + parameters to that function using the onCompleteParams property. The AS3 version even dispatches + a COMPLETE event when it finishes, so if you prefer to use addEventListener() instead of the callback, you can. + + - Loop or yoyo a set amount of times or inifinitely. For example, to have your TweenGroup yoyo (reverse() when + it has completed) 2 times, just do myGroup.yoyo = 2; (to loop twice instead, do myGroup.loop = 2) + + - Only adds about 4Kb to your SWF (not including TweenLite and OverwriteManager). + + At first glance, it may be difficult to see the value of using TweenGroup, but once you wrap your head around + it, you'll probably find all kinds of uses for it and wonder how you lived without it. For example, what if you + have a menu that flies out and unfolds using several sequenced tweens but when the user clicks elsewhere, you + want the menu to fold back into place. With TweenGroup, it's as simple as calling myGroup.reverse(). Or if you + have a bunch of tweens that play and then you want to loop them back to the beginning, just call myGroup.restart() + or set myGroup.progress = 0. + + +METHODS: + - pause():void + - resume():void + - restart(includeDelay:Boolean):void + - reverse(forcePlay:Boolean):void + - getActive():Array + - mergeGroup(group:TweenGroup, startIndex:Number):void + - updateTimeSpan():void + - clear(killTweens:Boolean):void + (also any EventDispatcher methods like addEventListener(), etc.) + +STATIC METHODS: + - allTo(targets:Array, duration:Number, vars:Object, BaseTweenClass:Class):TweenGroup + - allFrom(targets:Array, duration:Number, vars:Object, BaseTweenClass:Class):TweenGroup + - parse(tweens:Array, BaseTweenClass:Class):Array + +PROPERTIES: + - length : uint + - progress : Number + - progressWithDelay : Number + - paused : Boolean + - reversed : Boolean + - duration : Number [read-only] + - durationWithDelay : Number [read-only] + - align : String + - stagger : Number + - onComplete : Function + - onCompleteParams : Array + - loop : Number + - yoyo : Number + - tweens : Array + - timeScale : Number (only affects TweenMax instances) + + +EXAMPLES: + + To set up a simple sequence of 3 tweens that should be sequenced one after the other: + + import gs.*; + + var tween1:TweenLite = new TweenLite(mc, 1, {x:300}); + var tween2:TweenLite = new TweenLite(mc, 3, {y:400}); + var tween3:TweenMax = new TweenMax(mc, 2, {blurFilter:{blurX:10, blurY:10}}); + + var myGroup:TweenGroup = new TweenGroup([tween1, tween2, tween3]); + myGroup.align = TweenGroup.ALIGN_SEQUENCE; + + + Or if you don't mind all your tweens being the same type (TweenMax in this case as opposed to TweenLite), + you can do the same thing in less code like this: + + var myGroup:TweenGroup = new TweenGroup([{target:mc, time:1, x:300}, {target:mc, time:3, y:400}, {target:mc, time:2, blurFilter:{blurX:10, blurY:10}}], TweenMax, TweenGroup.ALIGN_SEQUENCE); + + + If you have an existing TweenGroup that you'd like to splice() a new tween into, it's as simple as: + + myGroup.splice(2, 0, new TweenLite(mc, 3, {alpha:0.5})); + + + To pause the group and skip to half-way through the overall progress, do: + + myGroup.pause(); + myGroup.progress = 0.5; + + +NOTES: + - This class adds about 4kb to your SWF (in addition to TweenLite and OverwriteManager which are about 4kb combined) + - The TweenMax.sequence(), TweenMax.multiSequence(), TweenMax.allTo(), and TweenMax.allFrom() methods have been deprecated in favor of + using TweenGroup because it is far more powerful and flexible. + - When you remove a tween from a group or replace it, that tween does NOT get killed automatically. + It will continue to run, so you need to use TweenLite.removeTween() to kill it. + - If you're running into problems with tweens simply not playing, it may be an overwriting issue. + Check out http://blog.greensock.com/overwritemanager/ for help. + - This is a brand new class, so please check back regularly for updates and let me know if + you run into any bugs/problems. + + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs { + import flash.events.*; + import flash.utils.*; + + dynamic public class TweenGroup extends Proxy implements IEventDispatcher { + public static const version:Number = 1.1; + public static const ALIGN_INIT:String = "init"; + public static const ALIGN_START:String = "start"; + public static const ALIGN_END:String = "end"; + public static const ALIGN_SEQUENCE:String = "sequence"; + public static const ALIGN_NONE:String = "none"; + + protected static var _overwriteMode:int = (OverwriteManager.enabled) ? OverwriteManager.mode : OverwriteManager.init(); //forces OverwriteManager to init() in AUTO mode (if it's not already initted) because AUTO overwriting is much more intuitive when working with sequences and groups. If you prefer to manage overwriting manually to save the 1kb, just comment this line out. + protected static var _TweenMax:Class; + protected static var _classInitted:Boolean; + protected static var _unexpired:Array = []; //TweenGroups that have not ended/expired yet (have endTimes in the future) + protected static var _prevTime:uint = 0; // records TweenLite.currentTime so that we can compare it on the checkExpiration() function to see if/when TweenGroups have completed. + + public var onComplete:Function; + public var onCompleteParams:Array; + public var loop:Number; + public var yoyo:Number; + public var endTime:Number; //time at which the last tween finishes (made it public for speed purposes) + public var expired:Boolean; + + protected var _tweens:Array; + protected var _pauseTime:Number; + protected var _startTime:Number; //time at which the first tween in the group begins (AFTER any delay) + protected var _initTime:Number; //same as _startTime except it factors in the delay, so it's basically _startTime minus the first tween's delay. + protected var _reversed:Boolean; + protected var _align:String; + protected var _stagger:Number; //time (in seconds) to stagger each tween in the group/sequence + protected var _repeatCount:Number; //number of times the group has yoyo'd or loop'd. + protected var _dispatcher:EventDispatcher; + + /** + * Constructor + * + * @param $tweens An Array of either TweenLite/TweenMax instances or Objects each containing at least a "target" and "time" property, like [{target:mc, time:2, x:300},{target:mc2, time:1, alpha:0.5}] + * @param $DefaultTweenClass Defines which tween class should be used when parsing objects that are not already TweenLite/TweenMax instances. Choices are TweenLite or TweenMax. + * @param $align Controls the alignment of the tweens within the group. Options are TweenGroup.ALIGN_SEQUENCE, TweenGroup.ALIGN_START, TweenGroup.ALIGN_END, TweenGroup.ALIGN_INIT, or TweenGroup.ALIGN_NONE + * @param $stagger Amount of time (in seconds) to offset each tween according to the current alignment. For example, if the align property is set to ALIGN_SEQUENCE and stagger is 0.5, this adds 0.5 seconds between each tween in the sequence. If align is set to ALIGN_START, it would add 0.5 seconds to the start time of each tween (0 for the first tween, 0.5 for the second, 1 for the third, etc.) + * */ + public function TweenGroup($tweens:Array=null, $DefaultTweenClass:Class=null, $align:String="none", $stagger:Number=0) { + super(); + if (!_classInitted) { + if (TweenLite.version < 10.092) { + trace("TweenGroup error! Please update your TweenLite class or try deleting your ASO files. TweenGroup requires a more recent version. Download updates at http://www.TweenLite.com."); + } + try { + _TweenMax = (getDefinitionByName("gs.TweenMax") as Class); //Checking "if (tween is _TweenMax)" is twice as fast as "if (tween.hasOwnProperty("paused"))". Storing a reference to the class this way prevents us from having to import the whole TweenMax class, thus saves a lot of Kb. + } catch ($e:Error) { + _TweenMax = Array; + } + TweenLite.timingSprite.addEventListener(Event.ENTER_FRAME, checkExpiration, false, -1, true); + _classInitted = true; + } + this.expired = true; + _repeatCount = 0; + _align = $align; + _stagger = $stagger; + _dispatcher = new EventDispatcher(this); + if ($tweens != null) { + _tweens = parse($tweens, $DefaultTweenClass); + updateTimeSpan(); + realign(); + } else { + _tweens = []; + _initTime = _startTime = this.endTime = 0; + } + } + + +//---- PROXY FUNCTIONS ------------------------------------------------------------------------------------------ + + flash_proxy override function callProperty($name:*, ...$args:Array):* { + var returnValue:* = _tweens[$name].apply(null, $args); + realign(); + if (!isNaN(_pauseTime)) { + pause(); //in case any tweens were added that weren't paused! + } + return returnValue; + } + + flash_proxy override function getProperty($prop:*):* { + return _tweens[$prop]; + } + + flash_proxy override function setProperty($prop:*, $value:*):void { + onSetProperty($prop, $value); + } + + protected function onSetProperty($prop:*, $value:*):void { + if (!isNaN($prop) && !($value is TweenLite)) { + trace("TweenGroup error: an attempt was made to add a non-TweenLite element."); + } else { + _tweens[$prop] = $value; + realign(); + if (!isNaN(_pauseTime) && ($value is TweenLite)) { + pauseTween($value as TweenLite); + } + } + } + + flash_proxy override function hasProperty($name:*):Boolean { + var props:String = " progress progressWithDelay duration durationWithDelay paused reversed timeScale align stagger tweens "; + if (_tweens.hasOwnProperty($name)) { + return true; + } else if (props.indexOf(" " + $name + " ") != -1) { + return true; + } else { + return false; + } + } + +//---- EVENT DISPATCHING FUNCTIONS ----------------------------------------------------------------------------- + + public function addEventListener($type:String, $listener:Function, $useCapture:Boolean = false, $priority:int = 0, $useWeakReference:Boolean = false):void { + _dispatcher.addEventListener($type, $listener, $useCapture, $priority, $useWeakReference); + } + + public function removeEventListener($type:String, $listener:Function, $useCapture:Boolean = false):void { + _dispatcher.removeEventListener($type, $listener, $useCapture); + } + + public function hasEventListener($type:String):Boolean { + return _dispatcher.hasEventListener($type); + } + + public function willTrigger($type:String):Boolean { + return _dispatcher.willTrigger($type); + } + + public function dispatchEvent($e:Event):Boolean { + return _dispatcher.dispatchEvent($e); + } + + +//---- PUBLIC FUNCTIONS ---------------------------------------------------------------------------------------- + + /** + * Pauses the entire group of tweens + */ + public function pause():void { + if (isNaN(_pauseTime)) { + _pauseTime = TweenLite.currentTime; + } + for (var i:int = _tweens.length - 1; i > -1; i--) { //this is outside the if() statement in case one (or more) tween is independently resumed() while the group is paused, and then the user wants to make sure all tweens in the group are paused. + if (_tweens[i].startTime != 999999999999999) { + pauseTween(_tweens[i]); + } + } + } + + /** + * Resumes the entire group of tweens + */ + public function resume():void { + var a:Array = [], i:int, time:Number = TweenLite.currentTime; + for (i = _tweens.length - 1; i > -1; i--) { + if (_tweens[i].startTime == 999999999999999) { + resumeTween(_tweens[i]); + a[a.length] = _tweens[i]; + } + if (_tweens[i].startTime >= time && !_tweens[i].enabled) { + _tweens[i].enabled = true; + _tweens[i].active = false; + } + } + if (!isNaN(_pauseTime)) { + var offset:Number = (TweenLite.currentTime - _pauseTime) / 1000; + _pauseTime = NaN; + offsetTime(a, offset); + } + } + + /** + * Restarts the entire group of tweens, optionally including any delay from the first tween. + * + * @param $includeDelay If true, any delay from the first tween (chronologically) is taken into account. + */ + public function restart($includeDelay:Boolean=false):void { + setProgress(0, $includeDelay); + _repeatCount = 0; + resume(); + } + + /** + * Reverses the entire group of tweens so that they appear to run backwards. If the group of tweens is partially finished when reverse() + * is called, the timing is automatically adjusted so that no skips/jumps occur. For example, if the entire group of tweens would take + * 10 seconds to complete (start to finish), and you call reverse() after 8 seconds, it will run the tweens backwards for another 8 seconds + * until the values are back to where they began. You may call reverse() as many times as you want and it will keep flipping the direction. + * So if you call reverse() twice, the group of tweens will be back to the original (forward) direction. + * + * @param $forcePlay Forces the group to resume() if it hasn't completed yet or restart() if it has. + */ + public function reverse($forcePlay:Boolean=true):void { + _reversed = !_reversed; + var i:int, tween:TweenLite, proxy:ReverseProxy, startTime:Number, initTime:Number, prog:Number, tScale:Number, timeOffset:Number = 0, isFinished:Boolean = false; + var time:Number = (!isNaN(_pauseTime)) ? _pauseTime : TweenLite.currentTime; + if (this.endTime <= time) { + timeOffset = int(this.endTime - time) + 1; + isFinished = true; + } + for (i = _tweens.length - 1; i > -1; i--) { + tween = _tweens[i]; + + if (tween is _TweenMax) { //TweenMax instances already have a "reverseEase()" function. I don't use "if (tween is TweenMax)" because it would bloat the file size by having to import TweenMax, so developers can just use this class with TweenLite to keep file size to a minimum if they so choose. + startTime = tween.startTime; + initTime = tween.initTime; + (tween as Object).reverse(false, false); + tween.startTime = startTime; + tween.initTime = initTime; + } else if (tween.ease != tween.vars.ease) { + tween.ease = tween.vars.ease; + } else { + proxy = new ReverseProxy(tween); + tween.ease = proxy.reverseEase; + } + + tScale = tween.combinedTimeScale; + prog = (((time - tween.initTime) / 1000) - tween.delay / tScale) / tween.duration * tScale; + startTime = int(time - ((1 - prog) * tween.duration * 1000 / tScale) + timeOffset); + tween.initTime = int(startTime - (tween.delay * (1000 / tScale))); + + if (tween.startTime != 999999999999999) { + tween.startTime = startTime; + } + if (tween.startTime > time) { //don't allow tweens with delays that haven't expired yet to be active + tween.enabled = true; + tween.active = false; + } + + } + updateTimeSpan(); + if ($forcePlay) { + if (isFinished) { + setProgress(0, true); + } + resume(); + } + } + + /** + * Provides an easy way to determine which tweens (if any) are currently active. Active tweens are not paused and are in the process of tweening values. + * + * @return An Array of TweenLite/TweenMax instances from the group that are currently active (in the process of tweening) + */ + public function getActive():Array { + var a:Array = []; + if (isNaN(_pauseTime)) { + var i:int, time:Number = TweenLite.currentTime; + for (i = _tweens.length - 1; i > -1; i--) { + if (getStartTime(_tweens[i]) <= time && getEndTime(_tweens[i]) >= time) { + a[a.length] = _tweens[i]; + } + } + } + return a; + } + + /** + * Merges (combines) two TweenGroups. You can even control the index at which the tweens are spliced in, or if you don't define one, the tweens will be added to the end. + * + * @param $group The TweenGroup to add + * @param $startIndex The index at which to start splicing the tweens from the new TweenGroup. For example, if tweenGroupA has 3 elements, and you want to add tweenGroupB's tweens right after the first one, you'd call tweenGroupA.mergeGroup(tweenGroupB, 1); + */ + public function mergeGroup($group:TweenGroup, $startIndex:Number=NaN):void { + if (isNaN($startIndex) || $startIndex > _tweens.length) { + $startIndex = _tweens.length; + } + var tweens:Array = $group.tweens; + var l:uint = tweens.length, i:int; + for (i = 0; i < l; i++) { + _tweens.splice($startIndex + i, 0, tweens[i]); + } + realign(); + } + + /** + * Removes all tweens from the group and kills the tweens using TweenLite.removeTween() + * + * @param $killTweens Determines whether or not all of the tweens are killed (as opposed to simply being removed from this group but continuing to remain in the rendering queue) + */ + public function clear($killTweens:Boolean=true):void { + for (var i:int = _tweens.length - 1; i > -1; i--) { + if ($killTweens) { + TweenLite.removeTween(_tweens[i], true); + } + _tweens[i] = null; + _tweens.splice(i, 1); + } + if (!this.expired) { + for (i = _unexpired.length - 1; i > -1; i--) { + if (_unexpired[i] == this) { + _unexpired.splice(i, 1); + break; + } + } + this.expired = true; + } + } + + /** + * Realigns all the tweens in the TweenGroup based on whatever the "align" property is set to. The only + * time you may need to call realign() is if you change a time-related property of an individual tween in the + * TweenGroup (like a tween's timeScale or duration). This is very uncommon. + */ + public function realign():void { + if (_align != ALIGN_NONE && _tweens.length > 1) { + var l:uint = _tweens.length, i:int, offset:Number = _stagger * 1000, prog:Number, rev:Boolean = _reversed; + + if (rev) { + prog = this.progressWithDelay; + reverse(); + this.progressWithDelay = 0; + } + + if (_align == ALIGN_SEQUENCE) { + setTweenInitTime(_tweens[0], _initTime); + for (i = 1; i < l; i++) { + setTweenInitTime(_tweens[i], getEndTime(_tweens[i - 1]) + offset); + } + + } else if (_align == ALIGN_INIT) { + for (i = 0; i < l; i++) { + setTweenInitTime(_tweens[i], _initTime + (offset * i)); + } + + } else if (_align == ALIGN_START) { + for (i = 0; i < l; i++) { + setTweenStartTime(_tweens[i], _startTime + (offset * i)); + } + + } else { //ALIGN_END + for (i = 0; i < l; i++) { + setTweenInitTime(_tweens[i], this.endTime - ((_tweens[i].delay + _tweens[i].duration) * 1000 / _tweens[i].combinedTimeScale) - (offset * i)); + } + } + + if (rev) { + reverse(); + this.progressWithDelay = prog; + } + + } + updateTimeSpan(); + } + + /** + * Analyzes all of the tweens in the group and determines the overall init, start, and end times as well as the overall duration which + * are necessary for accurate management. Normally a TweenGroup handles this internally, but if tweens are manipulated independently + * of TweenGroup or if a tween has its "loop" or "yoyo" special property set to true, it can cause these variables to become uncalibrated + * in which case you can use updateTimeSpan() to recalibrate. + */ + public function updateTimeSpan():void { + if (_tweens.length == 0) { + this.endTime = _startTime = _initTime = 0; + } else { + var i:int, start:Number, init:Number, end:Number, tween:TweenLite, repeats:int; + tween = _tweens[0]; + _initTime = tween.initTime; + + _startTime = _initTime + (tween.delay * (1000 / tween.combinedTimeScale)); + this.endTime = _startTime + (tween.duration * (1000 / tween.combinedTimeScale)); + + for (i = _tweens.length - 1; i > 0; i--) { + tween = _tweens[i]; + init = tween.initTime; + if (tween is _TweenMax && tween.initted && (!isNaN(tween.exposedVars.yoyo) || !isNaN(tween.exposedVars.loop))) { + repeats = (!isNaN(tween.exposedVars.yoyo)) ? tween.exposedVars.yoyo : tween.exposedVars.loop; + init -= (tween as Object).repeatCount * (tween.duration * 1000 / tween.combinedTimeScale); //resets the initTime (factoring in the loops/yoyo repeats) + } + + start = init + (tween.delay * (1000 / tween.combinedTimeScale)); + end = getEndTime(tween); + + if (init < _initTime) { + _initTime = init; + } + if (start < _startTime) { + _startTime = start; + } + if (end > this.endTime) { + this.endTime = end; + } + } + + if (this.expired && this.endTime > TweenLite.currentTime) { + this.expired = false; + _unexpired[_unexpired.length] = this; + } + + } + } + + public function toString():String { + return "TweenGroup( " + _tweens.toString() + " )"; + } + + +//---- STATIC PUBLIC FUNCTIONS ----------------------------------------------------------------------------------- + + /** + * Parses an Array that contains either TweenLite/TweenMax instances or Objects that are meant to define tween instances. + * Specifically, they must contain at LEAST "target" and "time" properties. For example: TweenGroup.parse([{target:mc1, time:2, x:300},{target:mc2, time:1, y:400}]); + * + * @param $tweens An Array of either TweenLite/TweenMax instances or Objects that are meant to define tween instances. For example [{target:mc1, time:2, x:300},{target:mc2, time:1, y:400}] + * @param $BaseTweenClass Defines which tween class should be used when parsing objects that are not already TweenLite/TweenMax instances. Choices are TweenLite or TweenMax. + * @return An Array with only TweenLite/TweenMax instances + */ + public static function parse($tweens:Array, $DefaultTweenClass:Class=null):Array { + if ($DefaultTweenClass == null) { + $DefaultTweenClass = TweenLite; + } + var a:Array = [], i:int, target:Object, duration:Number; + for (i = 0; i < $tweens.length; i++) { + if ($tweens[i] is TweenLite) { + a[a.length] = $tweens[i]; + } else { + target = $tweens[i].target; + duration = $tweens[i].time; + delete $tweens[i].target; + delete $tweens[i].time; + a[a.length] = new $DefaultTweenClass(target, duration, $tweens[i]); + } + } + return a; + } + + + /** + * Provides an easy way to tween multiple objects to the same values. It also accepts a few special properties, like "stagger" which + * staggers the start time of each tween. For example, you might want to have 5 MovieClips move down 100 pixels while fading out, and stagger + * the start times slightly by 0.2 seconds, you could do: + * TweenGroup.allTo([mc1, mc2, mc3, mc4, mc5], 1, {y:"100", alpha:0, stagger:0.2}); + * + * @param $targets An Array of objects to tween. + * @param $duration Duration (in seconds) of the tween + * @param $vars An object containing the end values of all the properties you'd like to have tweened (or if you're using the TweenGroup.allFrom() method, these variables would define the BEGINNING values). Additional special properties: "stagger", "onCompleteAll", and "onCompleteAllParams" + * @param $DefaultTweenClass Defines which tween class to use. Choices are TweenLite or TweenMax. + * @return TweenGroup instance + */ + public static function allTo($targets:Array, $duration:Number, $vars:Object, $DefaultTweenClass:Class=null):TweenGroup { + if ($DefaultTweenClass == null) { + $DefaultTweenClass = TweenLite; + } + var i:int, vars:Object, p:String; + var group:TweenGroup = new TweenGroup(null, $DefaultTweenClass, ALIGN_INIT, $vars.stagger || 0); + group.onComplete = $vars.onCompleteAll; + group.onCompleteParams = $vars.onCompleteAllParams; + delete $vars.stagger; + delete $vars.onCompleteAll; + delete $vars.onCompleteAllParams; + for (i = 0; i < $targets.length; i++) { + vars = {}; + for (p in $vars) { + vars[p] = $vars[p]; + } + group[group.length] = new $DefaultTweenClass($targets[i], $duration, vars); + } + if (group.stagger < 0) { + group.progressWithDelay = 0; + } + return group; + } + + /** + * Exactly the same as TweenGroup.allTo(), but instead of tweening the properties from where they're at currently to whatever you define, this tweens them the opposite way - from where you define TO where ever they are. This is handy for when things are set up on the stage the way they should end up and you just want to tween them into place. + * + * @param $targets An Array of objects to tween. + * @param $duration Duration (in seconds) of the tween + * @param $vars An object containing the beginning values of all the properties you'd like to have tweened. Additional special properties: "stagger", "onCompleteAll", and "onCompleteAllParams" + * @param $DefaultTweenClass Defines which tween class to use. Choices are TweenLite or TweenMax. + * @return TweenGroup instance + */ + public static function allFrom($targets:Array, $duration:Number, $vars:Object, $DefaultTweenClass:Class=null):TweenGroup { + $vars.runBackwards = true; + return allTo($targets, $duration, $vars, $DefaultTweenClass); + } + + +//---- PROTECTED STATIC FUNCTIONS ------------------------------------------------------------------------------- + + protected static function checkExpiration($e:Event):void { + var time:uint = TweenLite.currentTime, a:Array = _unexpired, tg:TweenGroup, i:int; + for (i = a.length - 1; i > -1; i--) { + tg = a[i]; + if (tg.endTime > _prevTime && tg.endTime <= time && !tg.paused) { + a.splice(i, 1); + tg.expired = true; + tg.handleCompletion(); + } + } + _prevTime = time; + } + + +//---- PROTECTED FUNCTIONS --------------------------------------------------------------------------------------- + + protected function offsetTime($tweens:Array, $offset:Number):void { + if ($tweens.length != 0) { + var ms:Number = $offset * 1000; //offset in milliseconds + var time:Number = (isNaN(_pauseTime)) ? TweenLite.currentTime : _pauseTime; + var tweens:Array = getRenderOrder($tweens, time); + var isPaused:Boolean, tween:TweenLite, render:Boolean, startTime:Number, end:Number, repeats:int, i:int, toRender:Array = []; + for (i = tweens.length - 1; i > -1; i--) { + tween = tweens[i]; + if (tween is _TweenMax && tween.initted && (!isNaN(tween.exposedVars.yoyo) || !isNaN(tween.exposedVars.loop))) { + repeats = (!isNaN(tween.exposedVars.yoyo)) ? tween.exposedVars.yoyo : tween.exposedVars.loop; + tween.initTime = tween.initTime + ms - ((tween as Object).repeatCount * (tween.duration * 1000 / tween.combinedTimeScale)); //resets the initTime (factoring in the loops/yoyo repeats) + } else { + tween.initTime += ms; + } + isPaused = Boolean(tween.startTime == 999999999999999); + + startTime = tween.initTime + (tween.delay * (1000 / tween.combinedTimeScale)); //this forces paused tweens with false start times to adjust to the normal one temporarily so that we can render it properly. + end = getEndTime(tween); + + render = ((startTime <= time || startTime - ms <= time) && (end >= time || end - ms >= time)); //only render what's necessary + + if (isNaN(_pauseTime) && end >= time) { + tween.enabled = true; //make sure they're in the rendering queue in case they were already completed! + } + if (!isPaused) { + tween.startTime = startTime; + } + if (startTime >= time) { //don't allow tweens with delays that haven't expired yet to be active + if (!tween.initted) { //otherwise a TweenGroup could be paused immediately after creation, then resumed later and if there's a sequential tween of an object, initTweenVals() could get called before the previous tweens finished running, meaning if the tweens pertain to the same property, the wrong value(s) could get recorded in the tweens Array + render = false; + } + tween.active = false; + } + if (render) { + toRender[toRender.length] = {tween:tween, startTime:startTime}; + } + } + + if ($offset > 0) { + toRender.sortOn("startTime", Array.NUMERIC); + } else { + toRender.sortOn("startTime", Array.NUMERIC | Array.DESCENDING); + } + + + for (i = toRender.length - 1; i > -1; i--) { + renderTween(toRender[i].tween, time); + } + + this.endTime += ms; + _startTime += ms; + _initTime += ms; + + if (this.expired && this.endTime > time) { + this.expired = false; + _unexpired[_unexpired.length] = this; + } + } + } + + protected function renderTween($tween:TweenLite, $time:Number):void { + var end:Number = getEndTime($tween), renderTime:Number, isPaused:Boolean; + if ($tween.startTime == 999999999999999) { + $tween.startTime = $tween.initTime + ($tween.delay * 1000 / $tween.combinedTimeScale); //this forces paused tweens with false start times to adjust to the normal one temporarily so that we can render it properly. + isPaused = true; + } + if (!$tween.initted) { + var active:Boolean = $tween.active; + $tween.active = false; + if (isPaused) { + $tween.initTweenVals(); + if ($tween.vars.onStart != null) { + $tween.vars.onStart.apply(null, $tween.vars.onStartParams); + } + } else { + $tween.activate(); //triggers the initTweenVals and fires the onStart() if necessary + } + $tween.active = active; + } + + if ($tween.startTime > $time) { //don't allow tweens with delays that haven't expired yet to be active + renderTime = $tween.startTime; + } else if (end < $time) { + renderTime = end; + } else { + renderTime = $time; + } + + if ($tween is _TweenMax && $tween.initted && (!isNaN($tween.exposedVars.yoyo) || !isNaN($tween.exposedVars.loop))) { + var repeats:int = (!isNaN($tween.exposedVars.yoyo)) ? $tween.exposedVars.yoyo : $tween.exposedVars.loop; + var count:int = int((renderTime - $tween.initTime - $tween.delay) / ($tween.duration * 1000 / $tween.combinedTimeScale)); + if (count > repeats) { + count = repeats; + } + ($tween as Object).repeatCount = count; + } + + if (renderTime < 0) { //render time is uint, so it must be zero or greater. + var originalStart:Number = $tween.startTime; + $tween.startTime -= renderTime; + $tween.render(0); + $tween.startTime = originalStart; + } else { + $tween.render(renderTime); + } + + if (isPaused) { + $tween.startTime = 999999999999999; + } + } + + /** + * If there are multiple tweens in the same group that control the same property of the same property, we need to make sure they're rendered in the correct + * order so that the one(s) closest in proximity to the current time is rendered last. Feed this function an Array of tweens and the time and it'll return + * an Array with them in the correct render order. + * + * @param $tweens An Array of tweens to get in the correct render order + * @param $time Time (in milliseconds) which defines the proximity point for each tween (typically the render time) + * @return An Array with the tweens in the correct render order + */ + protected function getRenderOrder($tweens:Array, $time:Number):Array { + var i:int, startTime:Number, postTweens:Array = [], preTweens:Array = [], a:Array = []; + for (i = $tweens.length - 1; i > -1; i--) { + startTime = getStartTime($tweens[i]); + if (startTime >= $time) { + postTweens[postTweens.length] = {start:startTime, tween:$tweens[i]}; + } else { + preTweens[preTweens.length] = {end:getEndTime($tweens[i]), tween:$tweens[i]}; + } + } + postTweens.sortOn("start", Array.NUMERIC); + preTweens.sortOn("end", Array.NUMERIC); + for (i = postTweens.length - 1; i > -1; i--) { + a[i] = postTweens[i].tween; + } + for (i = preTweens.length - 1; i > -1; i--) { + a[a.length] = preTweens[i].tween; + } + return a; + } + + protected function pauseTween($tween:TweenLite):void { + if ($tween is _TweenMax) { + ($tween as Object).pauseTime = _pauseTime; + } + $tween.startTime = 999999999999999; //for OverwriteManager + $tween.enabled = false; + } + + protected function resumeTween($tween:TweenLite):void { + if ($tween is _TweenMax) { + ($tween as Object).pauseTime = NaN; + } + $tween.startTime = $tween.initTime + ($tween.delay * (1000 / $tween.combinedTimeScale)); + } + + protected function getEndTime($tween:TweenLite):Number { + var dur:Number = $tween.duration * (1000 / $tween.combinedTimeScale); + if ($tween is _TweenMax && (!isNaN($tween.exposedVars.yoyo) || !isNaN($tween.exposedVars.loop))) { + var repeats:Number = (!isNaN($tween.exposedVars.yoyo)) ? $tween.exposedVars.yoyo : $tween.exposedVars.loop; + if (repeats == 0) { + return Infinity; + } + dur = (repeats - ($tween as Object).repeatCount + 1) * dur; + } + return $tween.initTime + ($tween.delay * 1000 / $tween.combinedTimeScale) + dur; + } + + protected function getInitTime($tween:TweenLite):Number { + if ($tween is _TweenMax && (!isNaN($tween.exposedVars.yoyo) || !isNaN($tween.exposedVars.loop))) { + return $tween.initTime - (($tween as Object).repeatCount * ($tween.duration * 1000 / $tween.combinedTimeScale)); + } else { + return $tween.initTime; + } + } + + protected function getStartTime($tween:TweenLite):Number { + return $tween.initTime + ($tween.delay * 1000 / $tween.combinedTimeScale); + } + + protected function setTweenInitTime($tween:TweenLite, $initTime:Number):void { + var offset:Number = $initTime - $tween.initTime; + $tween.initTime = $initTime; + if ($tween.startTime != 999999999999999) { //required for OverwriteManager (indicates a tween has been paused) + $tween.startTime += offset; + } + } + + protected function setTweenStartTime($tween:TweenLite, $startTime:Number):void { + var offset:Number = $startTime - getStartTime($tween); + $tween.initTime += offset; + if ($tween.startTime != 999999999999999) { //required for OverwriteManager (indicates a tween has been paused) + $tween.startTime = $startTime; + } + } + + protected function getProgress($includeDelay:Boolean=false):Number { + if (_tweens.length == 0) { + return 0; + } else { + var time:Number = (isNaN(_pauseTime)) ? TweenLite.currentTime : _pauseTime; + var min:Number = ($includeDelay) ? _initTime : _startTime; + var p:Number = (time - min) / (this.endTime - min); + if (p < 0) { + return 0; + } else if (p > 1) { + return 1; + } else { + return p; + } + } + } + + protected function setProgress($progress:Number, $includeDelay:Boolean=false):void { + if (_tweens.length != 0) { + var time:Number = (isNaN(_pauseTime)) ? TweenLite.currentTime : _pauseTime; + var min:Number = ($includeDelay) ? _initTime : _startTime; + offsetTime(_tweens, (time - (min + ((this.endTime - min) * $progress))) / 1000); + } + } + + public function handleCompletion():void { + if (!isNaN(this.yoyo) && (_repeatCount < this.yoyo || this.yoyo == 0)) { + _repeatCount++; + reverse(true); + } else if (!isNaN(this.loop) && (_repeatCount < this.loop || this.loop == 0)) { + _repeatCount++; + setProgress(0, true); + } + if (this.onComplete != null) { + this.onComplete.apply(null, this.onCompleteParams); + } + _dispatcher.dispatchEvent(new Event(Event.COMPLETE)); + } + + + +//---- GETTERS / SETTERS -------------------------------------------------------------------------------------------------- + + /** + * @return Number of tweens in the group + */ + public function get length():uint { + return _tweens.length; + } + + /** + * @return Overall progress of the group of tweens (not including any initial delay) as represented numerically between 0 and 1 where 0 means the group hasn't started, 0.5 means it is halfway finished, and 1 means it has completed. + */ + public function get progress():Number { + return getProgress(false); + } + /** + * Controls the overall progress of the group of tweens (not including any initial delay) as represented numerically between 0 and 1. + * + * @param $n Overall progress of the group of tweens (not including any initial delay) as represented numerically between 0 and 1 where 0 means the group hasn't started, 0.5 means it is halfway finished, and 1 means it has completed. + */ + public function set progress($n:Number):void { + setProgress($n, false); + } + + /** + * @return Overall progress of the group of tweens (including any initial delay) as represented numerically between 0 and 1 where 0 means the group hasn't started, 0.5 means it is halfway finished, and 1 means it has completed. + */ + public function get progressWithDelay():Number { + return getProgress(true); + } + /** + * Controls the overall progress of the group of tweens (including any initial delay) as represented numerically between 0 and 1. + * + * @param $n Overall progress of the group of tweens (including any initial delay) as represented numerically between 0 and 1 where 0 means the group hasn't started, 0.5 means it is halfway finished, and 1 means it has completed. + */ + public function set progressWithDelay($n:Number):void { + setProgress($n, true); + } + + /** + * @return Duration (in seconds) of the group of tweens NOT including any initial delay + */ + public function get duration():Number { + if (_tweens.length == 0) { + return 0; + } else { + return (this.endTime - _startTime) / 1000; + } + } + /** + * @return Duration (in seconds) of the group of tweens including any initial delay + */ + public function get durationWithDelay():Number { + if (_tweens.length == 0) { + return 0; + } else { + return (this.endTime - _initTime) / 1000; + } + } + + /** + * @return If the group of tweens is paused, this value will be true. Otherwise, it will be false. + */ + public function get paused():Boolean { + return (!isNaN(_pauseTime)); + } + /** + * Sets the paused state of the group of tweens + * + * @param $b Sets the paused state of the group of tweens. + */ + public function set paused($b:Boolean):void { + if ($b) { + pause(); + } else { + resume(); + } + } + + /** + * @return If the group of tweens is reversed, this value will be true. Otherwise, it will be false. + */ + public function get reversed():Boolean { + return _reversed; + } + /** + * Sets the reversed state of the group of tweens + * + * @param $b Sets the reversed state of the group of tweens. + */ + public function set reversed($b:Boolean):void { + if (_reversed != $b) { + reverse(true); + } + } + + /** + * @return timeScale property of the first TweenMax instance in the group (or 1 if there aren't any). Remember, timeScale edits do NOT affect TweenLite instances! + */ + public function get timeScale():Number { + for (var i:uint = 0; i < _tweens.length; i++) { + if (_tweens[i] is _TweenMax) { + return _tweens[i].timeScale; + } + } + return 1; + } + /** + * Changes the timeScale of all TweenMax instances in the TweenGroup. Remember, TweenLite instances are NOT affected by timeScale! + * + * @param $n time scale for all TweenMax instances in the TweenGroup. 1 is normal speed, 0.5 is half speed, 2 is double speed, etc. + */ + public function set timeScale($n:Number):void { + for (var i:int = _tweens.length - 1; i > -1; i--) { + if (_tweens[i] is _TweenMax) { + _tweens[i].timeScale = $n; + } + } + updateTimeSpan(); + } + + /** + * @return Alignment of the tweens within the group. possible values are "sequence", "start", "end", "init", and "none" + */ + public function get align():String { + return _align; + } + /** + * Controls the alignment of the tweens within the group. Typically it's best to use the constants TweenGroup.ALIGN_SEQUENCE, TweenGroup.ALIGN_START, TweenGroup.ALIGN_END, TweenGroup.ALIGN_INIT, or TweenGroup.ALIGN_NONE + * + * @param $s Sets the alignment of the tweens within the group. Typically it's best to use the constants TweenGroup.ALIGN_SEQUENCE, TweenGroup.ALIGN_START, TweenGroup.ALIGN_END, TweenGroup.ALIGN_INIT, or TweenGroup.ALIGN_NONE + */ + public function set align($s:String):void { + _align = $s; + realign(); + } + + /** + * @return Amount of time (in seconds) to offset each tween according to the current alignment. For example, if the align property is set to ALIGN_SEQUENCE and stagger is 0.5, this adds 0.5 seconds between each tween in the sequence. If align is set to ALIGN_START, it would add 0.5 seconds to the start time of each tween (0 for the first tween, 0.5 for the second, 1 for the third, etc.) + */ + public function get stagger():Number { + return _stagger; + } + /** + * Controls the amount of time (in seconds) to offset each tween according to the current alignment. For example, if the align property is set to ALIGN_SEQUENCE and stagger is 0.5, this adds 0.5 seconds between each tween in the sequence. If align is set to ALIGN_START, it would add 0.5 seconds to the start time of each tween (0 for the first tween, 0.5 for the second, 1 for the third, etc.) + * + * @param $s Amount of time (in seconds) to offset each tween according to the current alignment. For example, if the align property is set to ALIGN_SEQUENCE and stagger is 0.5, this adds 0.5 seconds between each tween in the sequence. If align is set to ALIGN_START, it would add 0.5 seconds to the start time of each tween (0 for the first tween, 0.5 for the second, 1 for the third, etc.) + */ + public function set stagger($n:Number):void { + _stagger = $n; + realign(); + } + + /** + * @return An Array of the tweens in this TweenGroup (this could be used to concat() with another TweenGroup for example) + */ + public function get tweens():Array { + return _tweens.slice(); + } + + } +} + +import gs.TweenLite; + +internal class ReverseProxy { + private var _tween:TweenLite; + + public function ReverseProxy($tween:TweenLite) { + _tween = $tween; + } + + public function reverseEase($t:Number, $b:Number, $c:Number, $d:Number):Number { + return _tween.vars.ease($d - $t, $b, $c, $d); + } + +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/TweenLite.as b/KalturaRecord/src/gs/TweenLite.as new file mode 100644 index 0000000..875d8be --- /dev/null +++ b/KalturaRecord/src/gs/TweenLite.as @@ -0,0 +1,552 @@ +/* +VERSION: 10.092 +DATE: 3/31/2009 +ACTIONSCRIPT VERSION: 3.0 (AS2 version is also available) +UPDATES & MORE DETAILED DOCUMENTATION AT: http://www.TweenLite.com +DESCRIPTION: + TweenLite is an extremely lightweight, FAST, and flexible tweening engine that serves as the core of + the GreenSock tweening platform. There are plenty of other tweening engines out there to choose from, + so here's why you might want to consider TweenLite: + + - SPEED - I'm not aware of any popular tweening engine with a similar feature set that's as fast + as TweenLite. See some speed comparisons yourself at http://blog.greensock.com/tweening-speed-test/ + + - Feature set - In addition to tweening ANY numeric property of ANY object, TweenLite can tween filters, + hex colors, volume, tint, and frames, and even do bezier tweening, plus LOTS more. TweenMax extends + TweenLite and adds even more capabilities like pause/resume, rounding, event listeners, and more. + Overwrite management is an important consideration for a tweening engine as well which is another + area where the GreenSock tweening platform shines. You have options for AUTO overwriting or you can + manually define how each tween will handle overlapping tweens of the same object. + + - Expandability - With its new plugin architecture, you can activate as many (or as few) features as your + project requires. Or write your own plugin if you need a feature that's unavailable. Minimize bloat, and + maximize performance. + + - Management features - TweenGroup makes it surprisingly simple to create complex sequences and groups + of TweenLite/Max tweens that you can pause(), resume(), restart(), or reverse(). You can even tween a TweenGroup's + progress property to fastforward or rewind the entire group/sequence. + + - Ease of use - Designers and Developers alike rave about how intuitive the GreenSock tweening platform is. + + - Updates - Frequent updates and feature additions make the GreenSock tweening platform reliable and robust. + + - AS2 and AS3 - Most other engines are only developed for AS2 or AS3 but not both. + + +PARAMETERS: + 1) $target : Object - Target object whose properties we're tweening + 2) $duration : Number - Duration (in seconds) of the tween + 3) $vars : Object - An object containing the end values of all the properties you'd like tweened (or if you're using + TweenLite.from(), these variables would define the BEGINNING values). For example, to tween + myClip's alpha to 0.5 over the course of 1 second, you'd do: TweenLite.to(myClip, 1, {alpha:0.5}). + +SPECIAL PROPERTIES (no plugins required): + Any of the following special properties can optionally be passed in through the $vars object (the third parameter): + + delay : Number - Amount of delay before the tween should begin (in seconds). + + ease : Function - Use any standard easing equation to control the rate of change. For example, + gs.easing.Elastic.easeOut. The Default is Regular.easeOut. + + easeParams : Array - An Array of extra parameters to feed the easing equation. This can be useful when + using an ease like Elastic and want to control extra parameters like the amplitude and period. + Most easing equations, however, don't require extra parameters so you won't need to pass in any easeParams. + + onStart : Function - If you'd like to call a function as soon as the tween begins, reference it here. + + onStartParams : Array - An Array of parameters to pass the onStart function. + + onUpdate : Function - If you'd like to call a function every time the property values are updated (on every frame during + the course of the tween), reference it here. + + onUpdateParams : Array - An Array of parameters to pass the onUpdate function + + onComplete : Function - If you'd like to call a function when the tween has finished, reference it here. + + onCompleteParams : Array - An Array of parameters to pass the onComplete function + + persist : Boolean - if true, the TweenLite instance will NOT automatically be removed by the garbage collector when it is complete. + However, it is still eligible to be overwritten by new tweens even if persist is true. By default, it is false. + + renderOnStart : Boolean - If you're using TweenLite.from() with a delay and want to prevent the tween from rendering until it + actually begins, set this to true. By default, it's false which causes TweenLite.from() to render + its values immediately, even before the delay has expired. + + overwrite : int - Controls how other tweens of the same object are handled when this tween is created. Here are the options: + - 0 (NONE): No tweens are overwritten. This is the fastest mode, but you need to be careful not to create any + tweens with overlapping properties, otherwise they'll conflict with each other. + + - 1 (ALL): (this is the default unless OverwriteManager.init() has been called) All tweens of the same object + are completely overwritten immediately when the tween is created. + TweenLite.to(mc, 1, {x:100, y:200}); + TweenLite.to(mc, 1, {x:300, delay:2, overwrite:1}); //immediately overwrites the previous tween + + - 2 (AUTO): (used by default if OverwriteManager.init() has been called) Searches for and overwrites only + individual overlapping properties in tweens that are active when the tween begins. + TweenLite.to(mc, 1, {x:100, y:200}); + TweenLite.to(mc, 1, {x:300, overwrite:2}); //only overwrites the "x" property in the previous tween + + - 3 (CONCURRENT): Overwrites all tweens of the same object that are active when the tween begins. + TweenLite.to(mc, 1, {x:100, y:200}); + TweenLite.to(mc, 1, {x:300, delay:2, overwrite:3}); //does NOT overwrite the previous tween because the first tween will have finished by the time this one begins. + + +PLUGINS: + There are many plugins that add capabilities through other special properties. Some examples are "tint", + "volume", "frame", "frameLabel", "bezier", "blurFilter", "colorMatrixFilter", "hexColors", and many more. + Adding the capabilities is as simple as activating the plugin with a single line of code, like TintPlugin.activate(); + Get information about all the plugins at http://blog.greensock.com/plugins/ + + +EXAMPLES: + Tween the alpha to 50% (0.5) and move the x position of a MovieClip named "clip_mc" + to 120 and fade the volume to 0 over the course of 1.5 seconds like so: + + import gs.*; + TweenLite.to(clip_mc, 1.5, {alpha:0.5, x:120, volume:0}); + + If you want to get more advanced and tween the clip_mc MovieClip over 5 seconds, changing the alpha to 0.5, + the x to 120 using the "Back.easeOut" easing function, delay starting the whole tween by 2 seconds, and then call + a function named "onFinishTween" when it has completed and pass a few parameters to that function (a value of + 5 and a reference to the clip_mc), you'd do so like: + + import gs.*; + import gs.easing.*; + TweenLite.to(clip_mc, 5, {alpha:0.5, x:120, ease:Back.easeOut, delay:2, onComplete:onFinishTween, onCompleteParams:[5, clip_mc]}); + function onFinishTween(argument1:Number, argument2:MovieClip):void { + trace("The tween has finished! argument1 = " + argument1 + ", and argument2 = " + argument2); + } + + If you have a MovieClip on the stage that is already in it's end position and you just want to animate it into + place over 5 seconds (drop it into place by changing its y property to 100 pixels higher on the screen and + dropping it from there), you could: + + import gs.*; + import gs.easing.*; + TweenLite.from(clip_mc, 5, {y:"-100", ease:Elastic.easeOut}); + + +NOTES: + + - The base TweenLite class adds about 2.9kb to your Flash file, but if you activate the extra features + that were available in versions prior to 10.0 (tint, removeTint, frame, endArray, visible, and autoAlpha), + it totals about 5k. You can easily activate those plugins by uncommenting out the associated lines of + code in the constructor. + + - Passing values as Strings will make the tween relative to the current value. For example, if you do + TweenLite.to(mc, 2, {x:"-20"}); it'll move the mc.x to the left 20 pixels which is the same as doing + TweenLite.to(mc, 2, {x:mc.x - 20}); You could also cast it like: TweenLite.to(mc, 2, {x:String(myVariable)}); + + - You can change the TweenLite.defaultEase function if you prefer something other than Regular.easeOut. + + - Kill all tweens for a particular object anytime with the TweenLite.killTweensOf(myClip_mc); + function. If you want to have the tweens forced to completion, pass true as the second parameter, + like TweenLite.killTweensOf(myClip_mc, true); + + - You can kill all delayedCalls to a particular function using TweenLite.killDelayedCallsTo(myFunction_func); + This can be helpful if you want to preempt a call. + + - Use the TweenLite.from() method to animate things into place. For example, if you have things set up on + the stage in the spot where they should end up, and you just want to animate them into place, you can + pass in the beginning x and/or y and/or alpha (or whatever properties you want). + + - If you find this class useful, please consider joining Club GreenSock which not only contributes + to ongoing development, but also gets you bonus classes (and other benefits) that are ONLY available + to members. Learn more at http://blog.greensock.com/club/ + + +CHANGE LOG: + + 10.091: + - Fixed bug that prevented timeScale tweens of TweenGroups + 10.09: + - Fixed bug with timeScale + 10.06: + - Speed improvements + - Integrated a new gs.utils.tween.TweenInfo class + - Minor internal changes + 10.0: + - Major update, shifting to a "plugin" architecture for handling special properties. + - Added "remove" property to all filter tweens to accommodate removing the filter at the end of the tween + - Added "setSize" and "frameLabel" plugins + - Speed enhancements + - Fixed minor overwrite bugs + 9.3: + - Added compatibility with TweenProxy and TweenProxy3D + 9.291: + - Adjusted how the timeScale special property is handled internally. It should be more flexible and slightly faster now. + 9.29: + - Minor speed enhancement + 9.26: + - Speed improvement and slight file size decrease + 9.25: + - Fixed bug with autoAlpha tweens working with TweenGroups when they're reversed. + 9.22: + - Fixed bug with from() when used in a TweenGroup + 9.12: + - Fixed but with TweenLiteVars, TweenFilterVars, and TweenMaxVars that caused "visible" to always get set at the end of a tween + 9.1: + - In AUTO or CONCURRENT mode, OverwriteManager doesn't handle overwriting until the tween actually begins which allows for immediate pause()-ing or re-ordering in TweenGroup, etc. + - Re-architected some inner-workings to further optimize for speed and reduce file size + 9.05: + - Fixed bug with killTweensOf() + - Fixed bug with from() + - Fixed bug with timeScale + 9.0: + - Made compatible with the new TweenGroup class (see http://blog.greensock.com/tweengroup/ for details) which allows for sequencing and much more + - Added clear() method + - Added a "clear" parameter to the removeTween() method + - Exposed TweenLite.currentTime as well as several other variables for compatibility with TweenGroup + 8.16: + - Fixed bug that prevented using another tween to gradually change the timeScale of a tween + 8.15: + - Fixed bug that caused from() delays not to function since version 8.14 + 8.14: + - Fixed bug in managing overwrites + 8.11: + - Added the ability to overwrite only individual overlapping properties with the new OverwriteManager class + - Added the killVars() method + - Fixed potential garbage collection issue + 7.04: + - Speed optimizations + 7.02: + - Added ability to tween the volume of any object that has a soundTransform property instead of just MoveiClips and SoundChannels. Now NetStream volumes can be tweened too. + 7.01: + - Fixed delayedCall() error (removed onCompleteScope since it's not useful in AS3 anyway) + 7.0: + - Added "persist" special property + - Added "removeTint" special property (please use this instead of tint:null) + - Added compatibility with TweenLiteVars utility class + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs { + import flash.display.*; + import flash.events.*; + import flash.utils.*; + + import gs.plugins.*; + import gs.utils.tween.*; + + public class TweenLite { + public static const version:Number = 10.092; + public static var plugins:Object = {}; + public static var killDelayedCallsTo:Function = TweenLite.killTweensOf; + public static var defaultEase:Function = TweenLite.easeOut; + public static var overwriteManager:Object; //makes it possible to integrate the gs.utils.tween.OverwriteManager for adding autoOverwrite capabilities + public static var currentTime:uint; + public static var masterList:Dictionary = new Dictionary(false); //Holds references to all our instances. + public static var timingSprite:Sprite = new Sprite(); //A reference to the sprite that we use to drive all our ENTER_FRAME events. + private static var _tlInitted:Boolean; //TweenLite class initted + private static var _timer:Timer = new Timer(2000); + protected static var _reservedProps:Object = {ease:1, delay:1, overwrite:1, onComplete:1, onCompleteParams:1, runBackwards:1, startAt:1, onUpdate:1, onUpdateParams:1, roundProps:1, onStart:1, onStartParams:1, persist:1, renderOnStart:1, proxiedEase:1, easeParams:1, yoyo:1, loop:1, onCompleteListener:1, onUpdateListener:1, onStartListener:1, orientToBezier:1, timeScale:1}; + + public var duration:Number; //Duration (in seconds) + public var vars:Object; //Variables (holds things like alpha or y or whatever we're tweening) + public var delay:Number; //Delay (in seconds) + public var startTime:Number; //Start time + public var initTime:Number; //Time of initialization. Remember, we can build in delays so this property tells us when the frame action was born, not when it actually started doing anything. + public var tweens:Array; //Contains parsed data for each property that's being tweened (target, property, start, change, name, and isPlugin). + public var target:Object; //Target object + public var active:Boolean; + public var ease:Function; + public var initted:Boolean; + public var combinedTimeScale:Number; //even though TweenLite doesn't use this variable TweenMax does and it optimized things to store it here, particularly for TweenGroup + public var gc:Boolean; //flagged for garbage collection + public var started:Boolean; + public var exposedVars:Object; //Helps when using TweenLiteVars and TweenMaxVars utility classes because certain properties are only exposed via vars.exposedVars (for example, the "visible" property is Boolean, so we cannot normally check to see if it's undefined) + + protected var _hasPlugins:Boolean; //if there are TweenPlugins in the tweens Array, we set this to true - it helps speed things up in onComplete + protected var _hasUpdate:Boolean; //has onUpdate. Tracking this as a Boolean value is faster than checking this.vars.onUpdate == null. + + public function TweenLite($target:Object, $duration:Number, $vars:Object) { + if ($target == null) { + return + } + if (!_tlInitted) { + + TweenPlugin.activate([ + + + //ACTIVATE (OR DEACTIVATE) PLUGINS HERE... + + TintPlugin, //tweens tints + RemoveTintPlugin, //allows you to remove a tint + FramePlugin, //tweens MovieClip frames + AutoAlphaPlugin, //tweens alpha and then toggles "visible" to false if/when alpha is zero + VisiblePlugin, //tweens a target's "visible" property + VolumePlugin, //tweens the volume of a MovieClip or SoundChannel or anything with a "soundTransform" property + EndArrayPlugin //tweens numbers in an Array + + + ]); + + + currentTime = getTimer(); + timingSprite.addEventListener(Event.ENTER_FRAME, updateAll, false, 0, true); + if (overwriteManager == null) { + overwriteManager = {mode:1, enabled:false}; + } + _timer.addEventListener("timer", killGarbage, false, 0, true); + _timer.start(); + _tlInitted = true; + } + this.vars = $vars; + this.duration = $duration || 0.001; //easing equations don't work when the duration is zero. + this.delay = $vars.delay || 0; + this.combinedTimeScale = $vars.timeScale || 1; + this.active = Boolean($duration == 0 && this.delay == 0); + this.target = $target; + if (typeof(this.vars.ease) != "function") { + this.vars.ease = defaultEase; + } + if (this.vars.easeParams != null) { + this.vars.proxiedEase = this.vars.ease; + this.vars.ease = easeProxy; + } + this.ease = this.vars.ease; + this.exposedVars = (this.vars.isTV == true) ? this.vars.exposedVars : this.vars; //for TweenLiteVars and TweenMaxVars (we need an object with enumerable properties) + this.tweens = []; + this.initTime = currentTime; + this.startTime = this.initTime + (this.delay * 1000); + + var mode:int = ($vars.overwrite == undefined || (!overwriteManager.enabled && $vars.overwrite > 1)) ? overwriteManager.mode : int($vars.overwrite); + if (!($target in masterList) || mode == 1) { + masterList[$target] = [this]; + } else { + masterList[$target].push(this); + } + + if ((this.vars.runBackwards == true && this.vars.renderOnStart != true) || this.active) { + initTweenVals(); + if (this.active) { //Means duration is zero and delay is zero, so render it now, but add one to the startTime because this.duration is always forced to be at least 0.001 since easing equations can't handle zero. + render(this.startTime + 1); + } else { + render(this.startTime); + } + if (this.exposedVars.visible != null && this.vars.runBackwards == true && (this.target is DisplayObject)) { + this.target.visible = this.exposedVars.visible; + } + } + } + + public function initTweenVals():void { + var p:String, i:int, plugin:*; + if (this.exposedVars.timeScale != undefined && this.target.hasOwnProperty("timeScale")) { + this.tweens[this.tweens.length] = new TweenInfo(this.target, "timeScale", this.target.timeScale, this.exposedVars.timeScale - this.target.timeScale, "timeScale", false); //[object, property, start, change, name, isPlugin] + } + for (p in this.exposedVars) { + if (p in _reservedProps) { + //ignore + + } else if (p in plugins) { + plugin = new plugins[p](); + if (plugin.onInitTween(this.target, this.exposedVars[p], this) == false) { + this.tweens[this.tweens.length] = new TweenInfo(this.target, p, this.target[p], (typeof(this.exposedVars[p]) == "number") ? this.exposedVars[p] - this.target[p] : Number(this.exposedVars[p]), p, false); //[object, property, start, change, name, isPlugin] + } else { + this.tweens[this.tweens.length] = new TweenInfo(plugin, "changeFactor", 0, 1, (plugin.overwriteProps.length == 1) ? plugin.overwriteProps[0] : "_MULTIPLE_", true); //[object, property, start, change, name, isPlugin] + _hasPlugins = true; + } + + } else { + this.tweens[this.tweens.length] = new TweenInfo(this.target, p, this.target[p], (typeof(this.exposedVars[p]) == "number") ? this.exposedVars[p] - this.target[p] : Number(this.exposedVars[p]), p, false); //[object, property, start, change, name, isPlugin] + } + } + if (this.vars.runBackwards == true) { + var ti:TweenInfo; + for (i = this.tweens.length - 1; i > -1; i--) { + ti = this.tweens[i]; + ti.start += ti.change; + ti.change = -ti.change; + } + } + if (this.vars.onUpdate != null) { + _hasUpdate = true; + } + if (TweenLite.overwriteManager.enabled && this.target in masterList) { + overwriteManager.manageOverwrites(this, masterList[this.target]); + } + this.initted = true; + } + + public function activate():void { + this.started = this.active = true; + if (!this.initted) { + initTweenVals(); + } + if (this.vars.onStart != null) { + this.vars.onStart.apply(null, this.vars.onStartParams); + } + if (this.duration == 0.001) { //In the constructor, if the duration is zero, we shift it to 0.001 because the easing functions won't work otherwise. We need to offset the this.startTime to compensate too. + this.startTime -= 1; + } + } + + public function render($t:uint):void { + var time:Number = ($t - this.startTime) * 0.001, factor:Number, ti:TweenInfo, i:int; + if (time >= this.duration) { + time = this.duration; + factor = (this.ease == this.vars.ease || this.duration == 0.001) ? 1 : 0; //to accommodate TweenMax.reverse(). Without this, the last frame would render incorrectly + } else { + factor = this.ease(time, 0, 1, this.duration); + } + for (i = this.tweens.length - 1; i > -1; i--) { + ti = this.tweens[i]; + ti.target[ti.property] = ti.start + (factor * ti.change); + } + if (_hasUpdate) { + this.vars.onUpdate.apply(null, this.vars.onUpdateParams); + } + if (time == this.duration) { + complete(true); + } + } + + public function complete($skipRender:Boolean = false):void { + if (!$skipRender) { + if (!this.initted) { + initTweenVals(); + } + this.startTime = currentTime - (this.duration * 1000) / this.combinedTimeScale; + render(currentTime); //Just to force the final render + return; + } + if (_hasPlugins) { + for (var i:int = this.tweens.length - 1; i > -1; i--) { + if (this.tweens[i].isPlugin && this.tweens[i].target.onComplete != null) { //function calls are expensive performance-wise, so don't call the plugin's onComplete() unless necessary. Most plugins don't require them. + this.tweens[i].target.onComplete(); + } + } + } + if (this.vars.persist != true) { + this.enabled = false; //moved above the onComplete callback in case there's an error in the user's onComplete - this prevents constant errors + } + if (this.vars.onComplete != null) { + this.vars.onComplete.apply(null, this.vars.onCompleteParams); + } + } + + public function clear():void { + this.tweens = []; + this.vars = this.exposedVars = {ease:this.vars.ease}; //just to avoid potential errors if someone tries to set the progress on a reversed tween that has been killed (unlikely, I know); + _hasUpdate = false; + } + + public function killVars($vars:Object):void { + if (overwriteManager.enabled) { + overwriteManager.killVars($vars, this.exposedVars, this.tweens); + } + } + + +//---- STATIC FUNCTIONS ------------------------------------------------------------------------- + + public static function to($target:Object, $duration:Number, $vars:Object):TweenLite { + return new TweenLite($target, $duration, $vars); + } + + public static function from($target:Object, $duration:Number, $vars:Object):TweenLite { + $vars.runBackwards = true; + return new TweenLite($target, $duration, $vars); + } + + public static function delayedCall($delay:Number, $onComplete:Function, $onCompleteParams:Array = null):TweenLite { + return new TweenLite($onComplete, 0, {delay:$delay, onComplete:$onComplete, onCompleteParams:$onCompleteParams, overwrite:0}); + } + + public static function updateAll($e:Event = null):void { + var time:uint = currentTime = getTimer(), ml:Dictionary = masterList, a:Array, i:int, tween:TweenLite; + for each (a in ml) { + for (i = a.length - 1; i > -1; i--) { + tween = a[i]; + if (tween.active) { + tween.render(time); + } else if (tween.gc) { + a.splice(i, 1); + } else if (time >= tween.startTime) { + tween.activate(); + tween.render(time); + } + } + } + } + + public static function removeTween($tween:TweenLite, $clear:Boolean = true):void { + if ($tween != null) { + if ($clear) { + $tween.clear(); + } + $tween.enabled = false; + } + } + + public static function killTweensOf($target:Object = null, $complete:Boolean = false):void { + if ($target != null && $target in masterList) { + var a:Array = masterList[$target], i:int, tween:TweenLite; + for (i = a.length - 1; i > -1; i--) { + tween = a[i]; + if ($complete && !tween.gc) { + tween.complete(false); + } + tween.clear(); //prevents situations where a tween is killed but is still referenced elsewhere and put back in the render queue, like if a TweenLiteGroup is paused, then the tween is removed, then the group is unpaused. + } + delete masterList[$target]; + } + } + + protected static function killGarbage($e:TimerEvent):void { + var ml:Dictionary = masterList, tgt:Object; + for (tgt in ml) { + if (ml[tgt].length == 0) { + delete ml[tgt]; + } + } + } + + public static function easeOut($t:Number, $b:Number, $c:Number, $d:Number):Number { + return -$c * ($t /= $d) * ($t - 2) + $b; + } + + +//---- PROXY FUNCTIONS ------------------------------------------------------------------------ + + protected function easeProxy($t:Number, $b:Number, $c:Number, $d:Number):Number { //Just for when easeParams are passed in via the vars object. + return this.vars.proxiedEase.apply(null, arguments.concat(this.vars.easeParams)); + } + + +//---- GETTERS / SETTERS ----------------------------------------------------------------------- + + public function get enabled():Boolean { + return (this.gc) ? false : true; + } + + public function set enabled($b:Boolean):void { + if ($b) { + if (!(this.target in masterList)) { + masterList[this.target] = [this]; + } else { + var a:Array = masterList[this.target], found:Boolean, i:int; + for (i = a.length - 1; i > -1; i--) { + if (a[i] == this) { + found = true; + break; + } + } + if (!found) { + a[a.length] = this; + } + } + } + this.gc = ($b) ? false : true; + if (this.gc) { + this.active = false; + } else { + this.active = this.started; + } + } + } + +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/TweenMax.as b/KalturaRecord/src/gs/TweenMax.as new file mode 100644 index 0000000..dd98306 --- /dev/null +++ b/KalturaRecord/src/gs/TweenMax.as @@ -0,0 +1,1015 @@ +/* +VERSION: 10.12 +DATE: 3/31/2009 +ACTIONSCRIPT VERSION: 3.0 (AS2 version is also available) +UPDATES & MORE DETAILED DOCUMENTATION AT: http://www.TweenMax.com +DESCRIPTION: + TweenMax extends the extremely lightweight, FAST TweenLite engine, adding many useful features + like pause/resume, timeScale, event listeners, reverse(), restart(), setDestination(), yoyo, loop, + rounding, and the ability to jump to any point in the tween using the "progress" property. It also + activates many extra plugins by default, making it extremely full-featured. Since TweenMax extends + TweenLite, it can do ANYTHING TweenLite can do plus much more. Same syntax. There are plenty of other + tweening engines out there to choose from, so here's why you might want to consider TweenMax: + + - SPEED - I'm not aware of any popular tweening engine with a similar feature set that's as fast + as TweenMax. See some speed comparisons yourself at http://blog.greensock.com/tweening-speed-test/ + + - Feature set - In addition to tweening ANY numeric property of ANY object, TweenMax can tween filters, + hex colors, volume, tint, frames, saturation, contrast, hue, colorization, brightness, and even do + bezier tweening, orientToBezier, pause/resume, reverse(), restart(), round values, jump to any point + in the tween with the "progress" property, automatically rotate in the shortest direction, plus LOTS more. + Overwrite management is an important consideration for a tweening engine as well which is another area + where the GreenSock tweening platform shines. You have options for AUTO overwriting or you can manually + define how each tween will handle overlapping tweens of the same object. + + - Expandability - With its new plugin architecture, you can activate as many (or as few) features as your + project requires. Or write your own plugin if you need a feature that's unavailable. Minimize bloat and + maximize performance. + + - Management features - TweenGroup makes it surprisingly simple to create complex sequences and groups + of TweenLite/Max tweens that you can pause(), resume(), restart(), or reverse(). You can even tween + a TweenGroup's progress property to fastforward or rewind the entire group/sequence. + + - Ease of use - Designers and Developers alike rave about how intuitive the GreenSock tweening platform is. + + - Updates - Frequent updates and feature additions make the GreenSock tweening platform reliable and robust. + + - AS2 and AS3 - Most other engines are only developed for AS2 or AS3 but not both. + + +PARAMETERS: + 1) $target : Object - Target object whose properties we're tweening + 2) $duration : Number - Duration (in seconds) of the tween + 3) $vars : Object - An object containing the end values of all the properties you'd like tweened (or if you're using + TweenMax.from(), these variables would define the BEGINNING values). For example, to tween + myClip's alpha to 0.5 over the course of 1 second, you'd do: TweenMax.to(myClip, 1, {alpha:0.5}). + +SPECIAL PROPERTIES (no plugins required): + Any of the following special properties can optionally be passed in through the $vars object (the third parameter): + + delay : Number - Amount of delay before the tween should begin (in seconds). + ease : Function - Use any standard easing equation to control the rate of change. For example, + gs.easing.Elastic.easeOut. The Default is Regular.easeOut. + easeParams : Array - An Array of extra parameters to feed the easing equation. This can be useful when + using an ease like Elastic and want to control extra parameters like the amplitude and period. + Most easing equations, however, don't require extra parameters so you won't need to pass in any easeParams. + onStart : Function - If you'd like to call a function as soon as the tween begins, reference it here. + onStartParams : Array - An Array of parameters to pass the onStart function. + onUpdate : Function - If you'd like to call a function every time the property values are updated (on every frame during + the course of the tween), reference it here. + onUpdateParams : Array - An Array of parameters to pass the onUpdate function + onComplete : Function - If you'd like to call a function when the tween has finished, reference it here. + onCompleteParams : Array - An Array of parameters to pass the onComplete function + persist : Boolean - if true, the TweenMax instance will NOT automatically be removed by the garbage collector when it is complete. + However, it is still eligible to be overwritten by new tweens even if persist is true. By default, it is false. + renderOnStart : Boolean - If you're using TweenMax.from() with a delay and want to prevent the tween from rendering until it + actually begins, set this to true. By default, it's false which causes TweenMax.from() to render + its values immediately, even before the delay has expired. + overwrite : int - Controls how other tweens of the same object are handled when this tween is created. Here are the options: + - 0 (NONE): No tweens are overwritten. This is the fastest mode, but you need to be careful not to create any + tweens with overlapping properties, otherwise they'll conflict with each other. + + - 1 (ALL): (this is the default unless OverwriteManager.init() has been called) All tweens of the same object + are completely overwritten immediately when the tween is created. + TweenMax.to(mc, 1, {x:100, y:200}); + TweenMax.to(mc, 1, {x:300, delay:2, overwrite:1}); //immediately overwrites the previous tween + + - 2 (AUTO): (used by default if OverwriteManager.init() has been called) Searches for and overwrites only + individual overlapping properties in tweens that are active when the tween begins. + TweenMax.to(mc, 1, {x:100, y:200}); + TweenMax.to(mc, 1, {x:300, overwrite:2}); //only overwrites the "x" property in the previous tween + + - 3 (CONCURRENT): Overwrites all tweens of the same object that are active when the tween begins. + TweenMax.to(mc, 1, {x:100, y:200}); + TweenMax.to(mc, 1, {x:300, delay:2, overwrite:3}); //does NOT overwrite the previous tween because the first tween will have finished by the time this one begins. + onStartListener : Function - A function to which the TweenMax instance should dispatch a TweenEvent when it begins. + This is the same as doing myTweenMaxInstance.addEventListener(TweenEvent.START, myFunction); + + onUpdateListener : Function - A function to which the TweenMax instance should dispatch a TweenEvent every time it updates values. + This is the same as doing myTweenMaxInstance.addEventListener(TweenEvent.UPDATE, myFunction); + + onCompleteListener : Function - A function to which the TweenMax instance should dispatch a TweenEvent when it completes. + This is the same as doing myTweenMaxInstance.addEventListener(TweenEvent.COMPLETE, myFunction); + + yoyo : Number - To make the tween reverse when it completes (like a yoyo) any number of times, set this to the number of cycles + you'd like the tween to yoyo. A value of zero causes the tween to yoyo endlessly. + + loop : Number - To make the tween repeat when it completes any number of times, set this to the number of cycles + you'd like the tween to loop. A value of zero causes the tween to loop endlessly. + + timeScale : Number - Multiplier that controls the speed of the tween (perceived duration) where 1 = normal speed, 0.5 = half speed, 2 = double speed, etc. + NOTE: There is also a static TweenMax.globalTimeScale property that affects ALL TweenMax and TweenFilterLite tweens (not TweenLite though) + + startAt : Object - Allows you to define the starting values for each property. Typically, TweenMax uses the current + value (whatever it happens to be at the time the tween begins) as the start value, but startAt + allows you to override that behavior. Simply pass an object in with whatever properties you'd like + to set just before the tween begins. For example, if mc.x is currently 100, and you'd like to + tween it from 0 to 500, do TweenMax.to(mc, 2, {x:500, startAt:{x:0}}); + + +PLUGINS: + There are many plugins that add capabilities through other special properties. Adding the capabilities + is as simple as activating the plugin with a single line of code, like SetSizePlugin.activate(); + Get information about all the plugins at http://blog.greensock.com/plugins/ + The following plugins are activated by default in TweenMax (you can easily prevent them from activating, + thus saving file size, by commenting out the associated activation lines of code in the constructor): + + autoAlpha : Number - Use it instead of the alpha property to gain the additional feature of toggling + the visible property to false when alpha reaches 0. It will also toggle visible + to true before the tween starts if the value of autoAlpha is greater than zero. + + visible : Boolean - To set a DisplayObject's "visible" property at the end of the tween, use this special property. + + volume : Number - Tweens the volume of an object with a soundTransform property (MovieClip/SoundChannel/NetStream, etc.) + + tint : Number - To change a DisplayObject's tint/color, set this to the hex value of the tint you'd like + to end up at(or begin at if you're using TweenMax.from()). An example hex value would be 0xFF0000. + + removeTint : Boolean - If you'd like to remove the tint that's applied to a DisplayObject, pass true for this special property. + + frame : Number - Use this to tween a MovieClip to a particular frame. + + bezier : Array - Bezier tweening allows you to tween in a non-linear way. For example, you may want to tween + a MovieClip's position from the origin (0,0) 500 pixels to the right (500,0) but curve downwards + through the middle of the tween. Simply pass as many objects in the bezier array as you'd like, + one for each "control point" (see documentation on Flash's curveTo() drawing method for more + about how control points work). In this example, let's say the control point would be at x/y coordinates + 250,50. Just make sure your my_mc is at coordinates 0,0 and then do: + TweenMax.to(my_mc, 3, {_x:500, _y:0, bezier:[{_x:250, _y:50}]}); + + bezierThrough : Array - Identical to bezier except that instead of passing bezier control point values, you + pass points through which the bezier values should move. This can be more intuitive + than using control points. + + orientToBezier : Array (or Boolean) - A common effect that designers/developers want is for a MovieClip/Sprite to + orient itself in the direction of a Bezier path (alter its rotation). orientToBezier + makes it easy. In order to alter a rotation property accurately, TweenMax needs 4 pieces + of information: + 1) Position property 1 (typically "x") + 2) Position property 2 (typically "y") + 3) Rotational property (typically "rotation") + 4) Number of degrees to add (optional - makes it easy to orient your MovieClip properly) + The orientToBezier property should be an Array containing one Array for each set of these values. + For maximum flexibility, you can pass in any number of arrays inside the container array, one + for each rotational property. This can be convenient when working in 3D because you can rotate + on multiple axis. If you're doing a standard 2D x/y tween on a bezier, you can simply pass + in a boolean value of true and TweenMax will use a typical setup, [["x", "y", "rotation", 0]]. + Hint: Don't forget the container Array (notice the double outer brackets) + + hexColors : Object - Although hex colors are technically numbers, if you try to tween them conventionally, + you'll notice that they don't tween smoothly. To tween them properly, the red, green, and + blue components must be extracted and tweened independently. TweenMax makes it easy. To tween + a property of your object that's a hex color to another hex color, use this special hexColors + property of TweenMax. It must be an OBJECT with properties named the same as your object's + hex color properties. For example, if your my_obj object has a "myHexColor" property that you'd like + to tween to red (0xFF0000) over the course of 2 seconds, do: + TweenMax.to(my_obj, 2, {hexColors:{myHexColor:0xFF0000}}); + You can pass in any number of hexColor properties. + + shortRotation : Number - To tween the rotation property of the target object in the shortest direction, use "shortRotation" + instead of "rotation" as the property. For example, if myObject.rotation is currently 170 degrees + and you want to tween it to -170 degrees, a normal rotation tween would travel a total of 340 degrees + in the counter-clockwise direction, but if you use shortRotation, it would travel 20 degrees in the + clockwise direction instead. + + roundProps : Array - If you'd like the inbetween values in a tween to always get rounded to the nearest integer, use the roundProps + special property. Just pass in an Array containing the property names that you'd like rounded. For example, + if you're tweening the x, y, and alpha properties of mc and you want to round the x and y values (not alpha) + every time the tween is rendered, you'd do: TweenMax.to(mc, 2, {x:300, y:200, alpha:0.5, roundProps:["x","y"]}); + + blurFilter : Object - To apply a BlurFilter, pass an object with one or more of the following properties: + blurX, blurY, quality + + glowFilter : Object - To apply a GlowFilter, pass an object with one or more of the following properties: + alpha, blurX, blurY, color, strength, quality, inner, knockout + + colorMatrixFilter : Object - To apply a ColorMatrixFilter, pass an object with one or more of the following properties: + colorize, amount, contrast, brightness, saturation, hue, threshold, relative, matrix + + dropShadowFilter : Object - To apply a DropShadowFilter, pass an object with one or more of the following properties: + alpha, angle, blurX, blurY, color, distance, strength, quality + + bevelFilter : Object - To apply a BevelFilter, pass an object with one or more of the following properties: + angle, blurX, blurY, distance, highlightAlpha, highlightColor, shadowAlpha, shadowColor, strength, quality + + +KEY PROPERTIES: + - progress : Number (0 - 1 where 0 = tween hasn't progressed, 0.5 = tween is halfway done, and 1 = tween is finished) + - timeScale : Number (Multiplier that controls the speed of the tween where 1 = normal speed, 0.5 = half speed, 2 = double speed, etc. ) + - paused : Boolean + - reversed : Boolean + +KEY METHODS: + - TweenMax.to(target:Object, duration:Number, vars:Object):TweenMax + - TweenMax.from(target:Object, duration:Number, vars:Object):TweenMax + - TweenMax.getTweensOf(target:Object):Array + - TweenMax.isTweening(target:Object):Boolean + - TweenMax.getAllTweens():Array + - TweenMax.killAllTweens(complete:Boolean):void + - TweenMax.killAllDelayedCalls(complete:Boolean):void + - TweenMax.pauseAll(tweens:Boolean, delayedCalls:Boolean):void + - TweenMax.resumeAll(tweens:Boolean, delayedCalls:Boolean):void + - TweenMax.delayedCall(delay:Number, function:Function, params:Array, persist:Boolean):TweenMax + - TweenMax.setGlobalTimeScale(scale:Number):void + - addEventListener(type:String, listener:Function, useCapture:Boolean, priority:int, useWeakReference:Boolean):void + - removeEventListener(type:String, listener:Function):void + - pause():void + - resume():void + - restart(includeDelay:Boolean):void + - reverse(adjustStart:Boolean, forcePlay:Boolean):void + - setDestination(property:String, value:*, adjustStartValues:Boolean):void + - invalidate(adjustStartValues:Boolean):void + - killProperties(names:Array):void + + +EXAMPLES: + + To tween the clip_mc MovieClip over 5 seconds, changing the alpha to 0.5, the x to 120 using the Back.easeOut + easing function, delay starting the whole tween by 2 seconds, and then call a function named "onFinishTween" when + it has completed and pass in a few parameters to that function (a value of 5 and a reference to the clip_mc), + you'd do so like: + + import gs.*; + import gs.easing.*; + TweenMax.to(clip_mc, 5, {alpha:0.5, x:120, ease:Back.easeOut, delay:2, onComplete:onFinishTween, onCompleteParams:[5, clip_mc]}); + function onFinishTween(argument1:Number, argument2:MovieClip):void { + trace("The tween has finished! argument1 = " + argument1 + ", and argument2 = " + argument2); + } + + If you have a MovieClip on the stage that is already in it's end position and you just want to animate it into + place over 5 seconds (drop it into place by changing its y property to 100 pixels higher on the screen and + dropping it from there), you could: + + import gs.*; + import gs.easing.*; + TweenMax.from(clip_mc, 5, {y:"-100", ease:Elastic.easeOut}); + + To set up an onUpdate listener (not callback) that traces the "progress" property of a tween, and another listener + that gets called when the tween completes, you could do: + + import gs.*; + import gs.events.TweenEvent; + + TweenMax.to(clip_mc, 2, {x:200, onUpdateListener:reportProgress, onCompleteListener:tweenFinished}); + function reportProgress($e:TweenEvent):void { + trace("tween progress: " + $e.target.progress); + } + function tweenFinished($e:TweenEvent):void { + trace("tween finished!"); + } + + +NOTES / HINTS: + + - Passing values as Strings will make the tween relative to the current value. For example, if you do + TweenMax.to(mc, 2, {x:"-20"}); it'll move the mc.x to the left 20 pixels which is the same as doing + TweenMax.to(mc, 2, {x:mc.x - 20}); You could also cast it like: TweenMax.to(mc, 2, {x:String(myVariable)}); + + - If you prefer, instead of using the onCompleteListener, onStartListener, and onUpdateListener special properties, + you can set up listeners the typical way, like: + var myTween:TweenMax = new TweenMax(my_mc, 2, {x:200}); + myTween.addEventListener(TweenEvent.COMPLETE, myFunction); + + - To tween an Array, just pass in an Array as a property named endArray like: + var myArray:Array = [1,2,3,4]; + TweenMax.to(myArray, 1.5, {endArray:[10,20,30,40]}); + + - You can kill all tweens of a particular object anytime with the TweenMax.killTweensOf(myObject); + function. If you want to have the tweens forced to completion, pass true as the second parameter, + like TweenMax.killTweensOf(myObject, true); + + - You can kill all delayedCalls to a particular function using TweenMax.killDelayedCallsTo(myFunction); + This can be helpful if you want to preempt a call. + + - Use the TweenMax.from() method to animate things into place. For example, if you have things set up on + the stage in the spot where they should end up, and you just want to animate them into place, you can + pass in the beginning x and/or y and/or alpha (or whatever properties you want). + + - If you find this class useful, please consider joining Club GreenSock which not only contributes + to ongoing development, but also gets you bonus classes (and other benefits) that are ONLY available + to members. Learn more at http://blog.greensock.com/club/ + + +CHANGE LOG: + 10.12: + - Added "repeatCount" property that allows you to see how many loops/yoyos have occured. + - Fixed bug with TweenGroup related to looping/yoyoing + 10.11: + - Fixed bug in setDestination() when adjustStartValues was false + - Fixed bug in startAt that caused it to wait one frame when the delay was zero. + 10.1: + - Fixed bug that caused error when "omit trace actions" was selected in publish settings. + 10.09: + - Fixed bug with timeScale + 10.08: + - Fixed bug in setDestination() + - Fixed bug in SetSizePlugin + - Fixed bug in isTweening() which didn't report true immediately after a tween was created. + 10.07: + - Fixed reporting of "paused" property being reversed + 10.06: + - Added "startAt" special property for defining starting values. + - Speed improvements + - Integrated a new gs.utils.tween.TweenInfo class + - Minor internal changes + 10.0: + - Major update, shifting to a "plugin" architecture for handling special properties. + - Eliminated TweenFilterLite and extended TweenLite instead + - Added "remove" property to all filter tweens to accommodate removing the filter at the end of the tween + - Added "setSize" and "frameLabel" plugins + - Speed enhancements + - Fixed minor overwrite bugs + - Updated the version to sync better with TweenLite (jumped from 3.6 to 10.0) + 3.6: + - Added compatibility with TweenProxy and TweenProxy3D + - Fixed bug with adding event listeners via TweenMaxVars + 3.52: + - Adjusted how the timeScale special property is handled internally. It should be more flexible and slightly faster now. + - Changed the way parseBeziers() stores values to make bezier tweening faster (Arrays instead of Objects with named properties) + 3.51: + - Fixed problem that caused killAllTweens() to not fully kill paused tweens + 3.5: + - Changed yoyo and loop behavior so that instead of being Boolean values that loop or yoyo endlessly, they're numbers so that you can define a specific number of cycles you'd like the tween to loop or yoyo. Zero causes the loop or yoyo to repeat endlessly. + 3.41: + - Fixed conflict between TweenMaxVars and the new shortRotation property in Flash Player 10 + 3.4: + - Added "shortRotation" special property + - Minor speed enhancement + 3.391: + - Minor change to make the timing of looping and yoyo-ing tweens more accurate (a few milliseconds could have been lost previously when the loop or yoyo was triggered) + 3.39: + - Speed improvement and slight file size decrease + 3.37: + - Fixed resumeAll() + 3.36: + - Fixed bug with autoAlpha tweens working with TweenGroups when they're reversed. + 3.35: + - Deprecated allTo() and allFrom() in favor of the much more powerful and flexible TweenGroup class (see http://blog.greensock.com/tweengroup/ for details) + 3.2: + - Added "roundProps" special property for rounding values + - Fixed but with TweenLiteVars, TweenFilterVars, and TweenMaxVars that caused "visible" to always get set at the end of a tween + 3.1: + - In AUTO or CONCURRENT mode, OverwriteManager doesn't handle overwriting until the tween actually begins which allows for immediate pause()-ing or re-ordering in TweenGroup, etc. + - Re-architected some inner-workings to further optimize for speed and reduce file size + 3.04: + - Fixed bug with killTweensOf() + - Fixed bug with reverse() + - Fixed bug with from() + 3.0: + - Deprecated sequence() and multiSequence() in favor of the much more powerful and flexible TweenGroup class (see http://blog.greensock.com/tweengroup/ for details) + - Added clear() method + - Added a "clear" parameter to the removeTween() method + - Exposed TweenLite.currentTime as well as several other TweenLite variables for compatibility with TweenGroup + 2.35: + - Fixed potential problem if multiple tweens used the same vars object and reverse() was called on more than one. + 2.34: + - Fixed problem with COMPLETE event listeners not firing when killTweensOf() was called with the forceComplete parameter set to true + 2.32: + - Fixed bug with invalidating() a tween with event listeners and adding an UPDATE listener after a tween is instantiated. + 2.31: + - invalidate() reparses onCompleteListener, onUpdateListener, and onStartListener special properties now. + - If a tween completed without persist:true and the globalTimeScale was updated between that time and the time restart(), reverse(), or resume() was called, it could have an incorrect timeScale. That's fixed now. + 2.3: + - Added setGlobalTimeScale() function to control the speed of all TweenFilterLite and TweenMax instances + - Added static "globalTimeScale" property to TweenMax and TweenFilterLite classes. You can even tween it like TweenLite.to(TweenMax, 1, {globalTimeScale:0.5}); + - Changed timeScale so that it also affects the delay (if any) + + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs { + import flash.events.*; + import flash.utils.*; + + import gs.events.TweenEvent; + import gs.plugins.*; + import gs.utils.tween.*; + + public class TweenMax extends TweenLite implements IEventDispatcher { + public static const version:Number = 10.12; + + private static var _activatedPlugins:Boolean = TweenPlugin.activate([ + + + //ACTIVATE (OR DEACTIVATE) PLUGINS HERE... + + TintPlugin, //tweens tints + RemoveTintPlugin, //allows you to remove a tint + FramePlugin, //tweens MovieClip frames + AutoAlphaPlugin, //tweens alpha and then toggles "visible" to false if/when alpha is zero + VisiblePlugin, //tweens a target's "visible" property + VolumePlugin, //tweens the volume of a MovieClip or SoundChannel or anything with a "soundTransform" property + EndArrayPlugin, //tweens numbers in an Array + + HexColorsPlugin, //tweens hex colors + BlurFilterPlugin, //tweens BlurFilters + ColorMatrixFilterPlugin, //tweens ColorMatrixFilters (including hue, saturation, colorize, contrast, brightness, and threshold) + BevelFilterPlugin, //tweens BevelFilters + DropShadowFilterPlugin, //tweens DropShadowFilters + GlowFilterPlugin, //tweens GlowFilters + RoundPropsPlugin, //enables the roundProps special property for rounding values. + BezierPlugin, //enables bezier tweening + BezierThroughPlugin, //enables bezierThrough tweening + ShortRotationPlugin //tweens rotation values in the shortest direction + + + ]); //activated in static var instead of constructor because otherwise if there's a from() tween, TweenLite's constructor would get called first and initTweenVals() would run before the plugins were activated. + + private static var _overwriteMode:int = (OverwriteManager.enabled) ? OverwriteManager.mode : OverwriteManager.init(); //OverwriteManager is optional for TweenLite and TweenFilterLite, but it is used by default in TweenMax. + public static var killTweensOf:Function = TweenLite.killTweensOf; + public static var killDelayedCallsTo:Function = TweenLite.killTweensOf; + public static var removeTween:Function = TweenLite.removeTween; + protected static var _pausedTweens:Dictionary = new Dictionary(false); //protects from garbage collection issues + protected static var _globalTimeScale:Number = 1; + protected var _dispatcher:EventDispatcher; + protected var _callbacks:Object; //stores the original onComplete, onStart, and onUpdate Functions from the this.vars Object (we replace them if/when dispatching events) + protected var _repeatCount:Number; //number of times the tween has yoyo'd or loop'd. + protected var _timeScale:Number; //Allows you to speed up or slow down a tween. Default is 1 (normal speed) 0.5 would be half-speed + public var pauseTime:Number; + + public function TweenMax($target:Object, $duration:Number, $vars:Object) { + super($target, $duration, $vars); + if (TweenLite.version < 10.092) { + trace("TweenMax error! Please update your TweenLite class or try deleting your ASO files. TweenMax requires a more recent version. Download updates at http://www.TweenMax.com."); + } + if (this.combinedTimeScale != 1 && this.target is TweenMax) { //in case the user is trying to tween the timeScale of another TweenFilterLite/TweenMax instance + _timeScale = 1; + this.combinedTimeScale = _globalTimeScale; + } else { + _timeScale = this.combinedTimeScale; + this.combinedTimeScale *= _globalTimeScale; //combining them speeds processing in important functions like render(). + } + if (this.combinedTimeScale != 1 && this.delay != 0) { + this.startTime = this.initTime + (this.delay * (1000 / this.combinedTimeScale)); + } + + if (this.vars.onCompleteListener != null || this.vars.onUpdateListener != null || this.vars.onStartListener != null) { + initDispatcher(); + if ($duration == 0 && this.delay == 0) { + onUpdateDispatcher(); + onCompleteDispatcher(); + } + } + _repeatCount = 0; + if (!isNaN(this.vars.yoyo) || !isNaN(this.vars.loop)) { + this.vars.persist = true; + } + if (this.delay == 0 && this.vars.startAt != null) { + this.vars.startAt.overwrite = 0; + new TweenMax(this.target, 0, this.vars.startAt); + } + } + + override public function initTweenVals():void { + if (this.vars.startAt != null && this.delay != 0) { + this.vars.startAt.overwrite = 0; + new TweenMax(this.target, 0, this.vars.startAt); + } + super.initTweenVals(); + //accommodate rounding if necessary... + if (this.exposedVars.roundProps is Array && TweenLite.plugins.roundProps != null) { + var i:int, j:int, prop:String, multiProps:String, rp:Array = this.exposedVars.roundProps, plugin:Object, ti:TweenInfo; + for (i = rp.length - 1; i > -1; i--) { + prop = rp[i]; + for (j = this.tweens.length - 1; j > -1; j--) { + ti = this.tweens[j]; + if (ti.name == prop) { + if (ti.isPlugin) { + ti.target.round = true; + } else { + if (plugin == null) { + plugin = new TweenLite.plugins.roundProps(); + plugin.add(ti.target, prop, ti.start, ti.change); + _hasPlugins = true; + this.tweens[j] = new TweenInfo(plugin, "changeFactor", 0, 1, prop, true); + } else { + plugin.add(ti.target, prop, ti.start, ti.change); //using a single plugin for rounding speeds processing + this.tweens.splice(j, 1); + } + } + } else if (ti.isPlugin && ti.name == "_MULTIPLE_" && !ti.target.round) { + multiProps = " " + ti.target.overwriteProps.join(" ") + " "; + if (multiProps.indexOf(" " + prop + " ") != -1) { + ti.target.round = true; + } + } + } + } + } + } + + public function pause():void { + if (isNaN(this.pauseTime)) { + this.pauseTime = currentTime; + this.startTime = 999999999999999; //required for OverwriteManager + this.enabled = false; + _pausedTweens[this] = this; + } + } + + public function resume():void { + this.enabled = true; + if (!isNaN(this.pauseTime)) { + this.initTime += currentTime - this.pauseTime; + this.startTime = this.initTime + (this.delay * (1000 / this.combinedTimeScale)); + this.pauseTime = NaN; + if (!this.started && currentTime >= this.startTime) { + activate(); //triggers onStart if necessary and initTweenVals() + } else { + this.active = this.started; + } + _pausedTweens[this] = null; + delete _pausedTweens[this]; + } + } + + public function restart($includeDelay:Boolean=false):void { + if ($includeDelay) { + this.initTime = currentTime; + this.startTime = currentTime + (this.delay * (1000 / this.combinedTimeScale)); + } else { + this.startTime = currentTime; + this.initTime = currentTime - (this.delay * (1000 / this.combinedTimeScale)); + } + _repeatCount = 0; + if (this.target != this.vars.onComplete) { //protects delayedCall()s from being rendered. + render(this.startTime); + } + this.pauseTime = NaN; + _pausedTweens[this] = null; + delete _pausedTweens[this]; + this.enabled = true; + } + + public function reverse($adjustDuration:Boolean=true, $forcePlay:Boolean=true):void { + this.ease = (this.vars.ease == this.ease) ? reverseEase : this.vars.ease; + var p:Number = this.progress; + if ($adjustDuration && p > 0) { + this.startTime = currentTime - ((1 - p) * this.duration * 1000 / this.combinedTimeScale); + this.initTime = this.startTime - (this.delay * (1000 / this.combinedTimeScale)); + } + if ($forcePlay != false) { + if (p < 1) { + resume(); + } else { + restart(); + } + } + } + + public function reverseEase($t:Number, $b:Number, $c:Number, $d:Number):Number { + return this.vars.ease($d - $t, $b, $c, $d); + } + + public function invalidate($adjustStartValues:Boolean=true):void { //forces the vars to be re-parsed and immediately re-rendered + if (this.initted) { + var p:Number = this.progress; + if (!$adjustStartValues && p != 0) { + this.progress = 0; + } + this.tweens = []; + _hasPlugins = false; + this.exposedVars = (this.vars.isTV == true) ? this.vars.exposedProps : this.vars; //for TweenLiteVars and TweenMaxVars + initTweenVals(); + _timeScale = this.vars.timeScale || 1; + this.combinedTimeScale = _timeScale * _globalTimeScale; + this.delay = this.vars.delay || 0; + if (isNaN(this.pauseTime)) { + this.startTime = this.initTime + (this.delay * 1000 / this.combinedTimeScale); + } + if (this.vars.onCompleteListener != null || this.vars.onUpdateListener != null || this.vars.onStartListener != null) { + if (_dispatcher != null) { + this.vars.onStart = _callbacks.onStart; + this.vars.onUpdate = _callbacks.onUpdate; + this.vars.onComplete = _callbacks.onComplete; + _dispatcher = null; + } + initDispatcher(); + } + if (p != 0) { + if ($adjustStartValues) { + adjustStartValues(); + } else { + this.progress = p; + } + } + } + } + + public function setDestination($property:String, $value:*, $adjustStartValues:Boolean=true):void { + var p:Number = this.progress, i:int, ti:TweenInfo; + if (this.initted) { + if (!$adjustStartValues) { + for (i = this.tweens.length - 1; i > -1; i--) { + ti = this.tweens[i]; + if (ti.name == $property) { + ti.target[ti.property] = ti.start; //return it to its start value (tween index values: [object, property, start, change, name]) + } + } + } + var varsOld:Object = this.vars; + var exposedVarsOld:Object = this.exposedVars; + var tweensOld:Array = this.tweens; + var hadPlugins:Boolean = _hasPlugins; + this.tweens = []; + this.vars = this.exposedVars = {}; + this.vars[$property] = $value; + initTweenVals(); + if (this.ease != reverseEase && varsOld.ease is Function) { + this.ease = varsOld.ease; + } + if ($adjustStartValues && p != 0) { + adjustStartValues(); + } + + var addedTweens:Array = this.tweens; + + this.vars = varsOld; + this.exposedVars = exposedVarsOld; + this.tweens = tweensOld; + + var killVars:Object = {}; + killVars[$property] = true; + for (i = this.tweens.length - 1; i > -1; i--) { + ti = this.tweens[i]; + if (ti.name == $property) { + this.tweens.splice(i, 1); + } else if (ti.isPlugin && ti.name == "_MULTIPLE_") { //is a plugin with multiple overwritable properties + ti.target.killProps(killVars); + if (ti.target.overwriteProps.length == 0) { + this.tweens.splice(i, 1); + } + } + } + + this.tweens = this.tweens.concat(addedTweens); + _hasPlugins = Boolean(hadPlugins || _hasPlugins); + } + this.vars[$property] = this.exposedVars[$property] = $value; + } + + protected function adjustStartValues():void { //adjusts the start values in the tweens so that the current progress and end values are maintained which prevents "skipping" when changing destination values mid-way through the tween. + var p:Number = this.progress; + if (p != 0) { + var factor:Number = this.ease(p, 0, 1, 1); + var inv:Number = 1 / (1 - factor); + var endValue:Number, ti:TweenInfo, i:int; + for (i = this.tweens.length - 1; i > -1; i--) { + ti = this.tweens[i]; + endValue = ti.start + ti.change; //[object, property, start, change, name, isPlugin] + if (ti.isPlugin) { //can't read the "progress" value of a plugin, but we know what it is based on the factor (above) + ti.change = (endValue - factor) * inv; + } else { + ti.change = (endValue - ti.target[ti.property]) * inv; + } + ti.start = endValue - ti.change; + } + } + } + + public function killProperties($names:Array):void { + var v:Object = {}, i:int; + for (i = $names.length - 1; i > -1; i--) { + v[$names[i]] = true; + } + killVars(v); + } + + override public function render($t:uint):void { + var time:Number = ($t - this.startTime) * 0.001 * this.combinedTimeScale, factor:Number, ti:TweenInfo, i:int; + if (time >= this.duration) { + time = this.duration; + factor = (this.ease == this.vars.ease || this.duration == 0.001) ? 1 : 0; //to accommodate TweenMax.reverse(). Without this, the last frame would render incorrectly + } else { + factor = this.ease(time, 0, 1, this.duration); + } + for (i = this.tweens.length - 1; i > -1; i--) { + ti = this.tweens[i]; + ti.target[ti.property] = ti.start + (factor * ti.change); //tween index values: [object, property, start, change, name, isPlugin] + } + if (_hasUpdate) { + this.vars.onUpdate.apply(null, this.vars.onUpdateParams); + } + if (time == this.duration) { //Check to see if we're done + complete(true); + } + } + + override public function complete($skipRender:Boolean = false):void { + if ((!isNaN(this.vars.yoyo) && (_repeatCount < this.vars.yoyo || this.vars.yoyo == 0)) || (!isNaN(this.vars.loop) && (_repeatCount < this.vars.loop || this.vars.loop == 0))) { + _repeatCount++; + if (!isNaN(this.vars.yoyo)) { + this.ease = (this.vars.ease == this.ease) ? reverseEase : this.vars.ease; + } + this.startTime = ($skipRender) ? this.startTime + (this.duration * (1000 / this.combinedTimeScale)) : currentTime; //for more accurate results, add the duration to the startTime, otherwise a few milliseconds might be skipped. You can occassionally see this if you have two simultaneous looping tweens with different end times that move objects that are butted up against each other. + this.initTime = this.startTime - (this.delay * (1000 / this.combinedTimeScale)); + } else if (this.vars.persist == true) { + //super.complete($skipRender); + pause(); + //return; + } + super.complete($skipRender); + } + + +//---- EVENT DISPATCHING ---------------------------------------------------------------------------------------------------------- + + protected function initDispatcher():void { + if (_dispatcher == null) { + _dispatcher = new EventDispatcher(this); + _callbacks = {onStart:this.vars.onStart, onUpdate:this.vars.onUpdate, onComplete:this.vars.onComplete}; //store the originals + if (this.vars.isTV == true) { //For TweenLiteVars, TweenFilterLiteVars, and TweenMaxVars compatibility + this.vars = this.vars.clone(); + } else { + var v:Object = {}, p:String; + for (p in this.vars) { + v[p] = this.vars[p]; //Just in case the same vars Object is reused for multiple tweens, we need to copy all the properties and create a duplicate so that we don't interfere with other tweens. + } + this.vars = v; + } + this.vars.onStart = onStartDispatcher; + this.vars.onComplete = onCompleteDispatcher; + + if (this.vars.onStartListener is Function) { + _dispatcher.addEventListener(TweenEvent.START, this.vars.onStartListener, false, 0, true); + } + if (this.vars.onUpdateListener is Function) { + _dispatcher.addEventListener(TweenEvent.UPDATE, this.vars.onUpdateListener, false, 0, true); + this.vars.onUpdate = onUpdateDispatcher; //To improve performance, we only want to add UPDATE dispatching if absolutely necessary. + _hasUpdate = true; + } + if (this.vars.onCompleteListener is Function) { + _dispatcher.addEventListener(TweenEvent.COMPLETE, this.vars.onCompleteListener, false, 0, true); + } + } + } + + protected function onStartDispatcher(... $args):void { + if (_callbacks.onStart != null) { + _callbacks.onStart.apply(null, this.vars.onStartParams); + } + _dispatcher.dispatchEvent(new TweenEvent(TweenEvent.START)); + } + + protected function onUpdateDispatcher(... $args):void { + if (_callbacks.onUpdate != null) { + _callbacks.onUpdate.apply(null, this.vars.onUpdateParams); + } + _dispatcher.dispatchEvent(new TweenEvent(TweenEvent.UPDATE)); + } + + protected function onCompleteDispatcher(... $args):void { + if (_callbacks.onComplete != null) { + _callbacks.onComplete.apply(null, this.vars.onCompleteParams); + } + _dispatcher.dispatchEvent(new TweenEvent(TweenEvent.COMPLETE)); + } + + public function addEventListener($type:String, $listener:Function, $useCapture:Boolean = false, $priority:int = 0, $useWeakReference:Boolean = false):void { + if (_dispatcher == null) { + initDispatcher(); + } + if ($type == TweenEvent.UPDATE && this.vars.onUpdate != onUpdateDispatcher) { //To improve performance, we only want to add UPDATE dispatching if absolutely necessary. + this.vars.onUpdate = onUpdateDispatcher; + _hasUpdate = true; + } + _dispatcher.addEventListener($type, $listener, $useCapture, $priority, $useWeakReference); + } + + public function removeEventListener($type:String, $listener:Function, $useCapture:Boolean = false):void { + if (_dispatcher != null) { + _dispatcher.removeEventListener($type, $listener, $useCapture); + } + } + + public function hasEventListener($type:String):Boolean { + if (_dispatcher == null) { + return false; + } else { + return _dispatcher.hasEventListener($type); + } + } + + public function willTrigger($type:String):Boolean { + if (_dispatcher == null) { + return false; + } else { + return _dispatcher.willTrigger($type); + } + } + + public function dispatchEvent($e:Event):Boolean { + if (_dispatcher == null) { + return false; + } else { + return _dispatcher.dispatchEvent($e); + } + } + + +//---- STATIC FUNCTIONS ----------------------------------------------------------------------------------------------------------- + + public static function to($target:Object, $duration:Number, $vars:Object):TweenMax { + return new TweenMax($target, $duration, $vars); + } + + public static function from($target:Object, $duration:Number, $vars:Object):TweenMax { + $vars.runBackwards = true; + return new TweenMax($target, $duration, $vars); + } + + public static function delayedCall($delay:Number, $onComplete:Function, $onCompleteParams:Array=null, $persist:Boolean=false):TweenMax { + return new TweenMax($onComplete, 0, {delay:$delay, onComplete:$onComplete, onCompleteParams:$onCompleteParams, persist:$persist, overwrite:0}); + } + + public static function setGlobalTimeScale($scale:Number):void { + if ($scale < 0.00001) { + $scale = 0.00001; + } + var ml:Dictionary = masterList, i:int, a:Array; + _globalTimeScale = $scale; + for each (a in ml) { + for (i = a.length - 1; i > -1; i--) { + if (a[i] is TweenMax) { + a[i].timeScale *= 1; //just forces combining of the _timeScale and _globalTimeScale. + } + } + } + } + + public static function getTweensOf($target:Object):Array { + var a:Array = masterList[$target]; + var toReturn:Array = []; + if(a != null) { + for (var i:int = a.length - 1; i > -1; i--) { + if (!a[i].gc) { + toReturn[toReturn.length] = a[i]; + } + } + } + for each (var tween:TweenLite in _pausedTweens) { + if (tween.target == $target) { + toReturn[toReturn.length] = tween; + } + } + return toReturn; + } + + public static function isTweening($target:Object):Boolean { + var a:Array = getTweensOf($target); + for (var i:int = a.length - 1; i > -1; i--) { + if ((a[i].active || a[i].startTime == currentTime) && !a[i].gc) { + return true; + } + } + return false; + } + + public static function getAllTweens():Array { + var ml:Dictionary = masterList; //speeds things up slightly + var toReturn:Array = [], a:Array, i:int, tween:TweenLite; + for each (a in ml) { + for (i = a.length - 1; i > -1; i--) { + if (!a[i].gc) { + toReturn[toReturn.length] = a[i]; + } + } + } + for each (tween in _pausedTweens) { + toReturn[toReturn.length] = tween; + } + return toReturn; + } + + public static function killAllTweens($complete:Boolean = false):void { + killAll($complete, true, false); + } + + public static function killAllDelayedCalls($complete:Boolean = false):void { + killAll($complete, false, true); + } + + public static function killAll($complete:Boolean = false, $tweens:Boolean = true, $delayedCalls:Boolean = true):void { + var a:Array = getAllTweens(); + var isDC:Boolean, i:int; //is delayedCall + for (i = a.length - 1; i > -1; i--) { + isDC = (a[i].target == a[i].vars.onComplete); + if (isDC == $delayedCalls || isDC != $tweens) { + if ($complete) { + a[i].complete(false); + a[i].clear(); + } else { + TweenLite.removeTween(a[i], true); + } + } + } + } + + public static function pauseAll($tweens:Boolean = true, $delayedCalls:Boolean = false):void { + changePause(true, $tweens, $delayedCalls); + } + + public static function resumeAll($tweens:Boolean = true, $delayedCalls:Boolean = false):void { + changePause(false, $tweens, $delayedCalls); + } + + public static function changePause($pause:Boolean, $tweens:Boolean = true, $delayedCalls:Boolean = false):void { + var a:Array = getAllTweens(); + var isDC:Boolean; //is delayedCall + for (var i:int = a.length - 1; i > -1; i--) { + isDC = (a[i].target == a[i].vars.onComplete); + if (a[i] is TweenMax && (isDC == $delayedCalls || isDC != $tweens)) { + a[i].paused = $pause; + } + } + } + + +//---- GETTERS / SETTERS ---------------------------------------------------------------------------------------------------------- + + public function get paused():Boolean { + return !isNaN(this.pauseTime); + } + public function set paused($b:Boolean):void { + if ($b) { + pause(); + } else { + resume(); + } + } + public function get reversed():Boolean { + return (this.ease == reverseEase); + } + public function set reversed($b:Boolean):void { + if (this.reversed != $b) { + reverse(); + } + } + public function get timeScale():Number { + return _timeScale; + } + public function set timeScale($n:Number):void { + if ($n < 0.00001) { + $n = _timeScale = 0.00001; + } else { + _timeScale = $n; + $n *= _globalTimeScale; //instead of doing _timeScale * _globalTimeScale in the render() and elsewhere, we improve performance by combining them here. + } + this.initTime = currentTime - ((currentTime - this.initTime - (this.delay * (1000 / this.combinedTimeScale))) * this.combinedTimeScale * (1 / $n)) - (this.delay * (1000 / $n)); + if (this.startTime != 999999999999999) { //required for OverwriteManager (indicates a TweenMax instance that has been paused) + this.startTime = this.initTime + (this.delay * (1000 / $n)); + } + this.combinedTimeScale = $n; + } + override public function set enabled($b:Boolean):void { + if (!$b) { + _pausedTweens[this] = null; + delete _pausedTweens[this]; + } + super.enabled = $b; + if ($b) { + this.combinedTimeScale = _timeScale * _globalTimeScale; + } + } + public static function set globalTimeScale($n:Number):void { + setGlobalTimeScale($n); + } + public static function get globalTimeScale():Number { + return _globalTimeScale; + } + public function get repeatCount():Number { + return _repeatCount; + } + public function set repeatCount($n:Number):void { + _repeatCount = $n; + } + public function get progress():Number { + var t:Number = (!isNaN(this.pauseTime)) ? this.pauseTime : currentTime; + var p:Number = (((t - this.initTime) * 0.001) - this.delay / this.combinedTimeScale) / this.duration * this.combinedTimeScale; + if (p > 1) { + return 1; + } else if (p < 0) { + return 0; + } else { + return p; + } + } + public function set progress($n:Number):void { + this.startTime = currentTime - ((this.duration * $n) * 1000); + this.initTime = this.startTime - (this.delay * (1000 / this.combinedTimeScale)); + if (!this.started) { + activate();//Just to trigger all the onStart stuff and make sure initTweenVals() has been called. + } + render(currentTime); + + if (!isNaN(this.pauseTime)) { + this.pauseTime = currentTime; + this.startTime = 999999999999999; //required for OverwriteManager + this.active = false; + } + } + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/easing/Back.as b/KalturaRecord/src/gs/easing/Back.as new file mode 100644 index 0000000..b0423fa --- /dev/null +++ b/KalturaRecord/src/gs/easing/Back.as @@ -0,0 +1,14 @@ +package gs.easing { + public class Back { + public static function easeIn (t:Number, b:Number, c:Number, d:Number, s:Number = 1.70158):Number { + return c*(t/=d)*t*((s+1)*t - s) + b; + } + public static function easeOut (t:Number, b:Number, c:Number, d:Number, s:Number = 1.70158):Number { + return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b; + } + public static function easeInOut (t:Number, b:Number, c:Number, d:Number, s:Number = 1.70158):Number { + if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b; + return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b; + } + } +} diff --git a/KalturaRecord/src/gs/easing/Bounce.as b/KalturaRecord/src/gs/easing/Bounce.as new file mode 100644 index 0000000..31cbdee --- /dev/null +++ b/KalturaRecord/src/gs/easing/Bounce.as @@ -0,0 +1,22 @@ +package gs.easing { + public class Bounce { + public static function easeOut (t:Number, b:Number, c:Number, d:Number):Number { + if ((t/=d) < (1/2.75)) { + return c*(7.5625*t*t) + b; + } else if (t < (2/2.75)) { + return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b; + } else if (t < (2.5/2.75)) { + return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b; + } else { + return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b; + } + } + public static function easeIn (t:Number, b:Number, c:Number, d:Number):Number { + return c - easeOut(d-t, 0, c, d) + b; + } + public static function easeInOut (t:Number, b:Number, c:Number, d:Number):Number { + if (t < d/2) return easeIn (t*2, 0, c, d) * .5 + b; + else return easeOut (t*2-d, 0, c, d) * .5 + c*.5 + b; + } + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/easing/Circ.as b/KalturaRecord/src/gs/easing/Circ.as new file mode 100644 index 0000000..d201b10 --- /dev/null +++ b/KalturaRecord/src/gs/easing/Circ.as @@ -0,0 +1,14 @@ +package gs.easing { + public class Circ { + public static function easeIn (t:Number, b:Number, c:Number, d:Number):Number { + return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b; + } + public static function easeOut (t:Number, b:Number, c:Number, d:Number):Number { + return c * Math.sqrt(1 - (t=t/d-1)*t) + b; + } + public static function easeInOut (t:Number, b:Number, c:Number, d:Number):Number { + if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b; + return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b; + } + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/easing/Cubic.as b/KalturaRecord/src/gs/easing/Cubic.as new file mode 100644 index 0000000..2163f3c --- /dev/null +++ b/KalturaRecord/src/gs/easing/Cubic.as @@ -0,0 +1,14 @@ +package gs.easing { + public class Cubic { + public static function easeIn (t:Number, b:Number, c:Number, d:Number):Number { + return c*(t/=d)*t*t + b; + } + public static function easeOut (t:Number, b:Number, c:Number, d:Number):Number { + return c*((t=t/d-1)*t*t + 1) + b; + } + public static function easeInOut (t:Number, b:Number, c:Number, d:Number):Number { + if ((t/=d/2) < 1) return c/2*t*t*t + b; + return c/2*((t-=2)*t*t + 2) + b; + } + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/easing/EaseLookup.as b/KalturaRecord/src/gs/easing/EaseLookup.as new file mode 100644 index 0000000..ba83fe6 --- /dev/null +++ b/KalturaRecord/src/gs/easing/EaseLookup.as @@ -0,0 +1,69 @@ +package gs.easing { +/** + * EaseLookup enables you to find the easing function associated with a particular name (String), + * like "strongEaseOut" which can be useful when loading in XML data that comes in as Strings but + * needs to be translated to native function references. + * + * Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. + * + * @author Jack Doyle, jack@greensock.com + */ + public class EaseLookup { + /** @private **/ + private static var _lookup:Object; + + /** + * Finds the easing function associated with a particular name (String), like "strongEaseOut". This can be useful when + * loading in XML data that comes in as Strings but needs to be translated to native function references. You can pass in + * the name with or without the period, and it is case insensitive, so any of the following will find the Strong.easeOut function:

+ * EaseLookup.find("Strong.easeOut")
+ * EaseLookup.find("strongEaseOut")
+ * EaseLookup.find("strongeaseout")

+ * + * You can translate Strings directly when tweening, like this:
+ * TweenLite.to(mc, 1, {x:100, ease:EaseLookup.find(myString)});

+ * + * @param $name The name of the easing function, with or without the period and case insensitive (i.e. "Strong.easeOut" or "strongEaseOut") + * @return The easing function associated with the name + */ + public static function find($name:String):Function { + if (_lookup == null) { + buildLookup(); + } + return _lookup[$name.toLowerCase()]; + } + + /** @private **/ + private static function buildLookup():void { + _lookup = {}; + + addInOut(Back, ["back"]); + addInOut(Bounce, ["bounce"]); + addInOut(Circ, ["circ", "circular"]); + addInOut(Cubic, ["cubic"]); + addInOut(Elastic, ["elastic"]); + addInOut(Expo, ["expo", "exponential"]); + addInOut(Linear, ["linear"]); + addInOut(Quad, ["quad", "quadratic"]); + addInOut(Quart, ["quart","quartic"]); + addInOut(Quint, ["quint", "quintic", "strong"]); + addInOut(Sine, ["sine"]); + + _lookup["linear.easenone"] = _lookup["lineareasenone"] = Linear.easeNone; + } + + /** @private **/ + private static function addInOut($class:Class, $names:Array):void { + var name:String; + var i:int = $names.length; + while (i-- > 0) { + name = $names[i].toLowerCase(); + _lookup[name + ".easein"] = _lookup[name + "easein"] = $class.easeIn; + _lookup[name + ".easeout"] = _lookup[name + "easeout"] = $class.easeOut; + _lookup[name + ".easeinout"] = _lookup[name + "easeinout"] = $class.easeInOut; + } + } + + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/easing/Elastic.as b/KalturaRecord/src/gs/easing/Elastic.as new file mode 100644 index 0000000..ab50719 --- /dev/null +++ b/KalturaRecord/src/gs/easing/Elastic.as @@ -0,0 +1,28 @@ +package gs.easing { + public class Elastic { + private static const _2PI:Number = Math.PI * 2; + + public static function easeIn (t:Number, b:Number, c:Number, d:Number, a:Number = 0, p:Number = 0):Number { + var s:Number; + if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; + if (!a || a < Math.abs(c)) { a=c; s = p/4; } + else s = p/_2PI * Math.asin (c/a); + return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*_2PI/p )) + b; + } + public static function easeOut (t:Number, b:Number, c:Number, d:Number, a:Number = 0, p:Number = 0):Number { + var s:Number; + if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; + if (!a || a < Math.abs(c)) { a=c; s = p/4; } + else s = p/_2PI * Math.asin (c/a); + return (a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*_2PI/p ) + c + b); + } + public static function easeInOut (t:Number, b:Number, c:Number, d:Number, a:Number = 0, p:Number = 0):Number { + var s:Number; + if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5); + if (!a || a < Math.abs(c)) { a=c; s = p/4; } + else s = p/_2PI * Math.asin (c/a); + if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*_2PI/p )) + b; + return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*_2PI/p )*.5 + c + b; + } + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/easing/Expo.as b/KalturaRecord/src/gs/easing/Expo.as new file mode 100644 index 0000000..5364dec --- /dev/null +++ b/KalturaRecord/src/gs/easing/Expo.as @@ -0,0 +1,16 @@ +package gs.easing { + public class Expo { + public static function easeIn(t:Number, b:Number, c:Number, d:Number):Number { + return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b - c * 0.001; + } + public static function easeOut(t:Number, b:Number, c:Number, d:Number):Number { + return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b; + } + public static function easeInOut(t:Number, b:Number, c:Number, d:Number):Number { + if (t==0) return b; + if (t==d) return b+c; + if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b; + return c/2 * (-Math.pow(2, -10 * --t) + 2) + b; + } + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/easing/Linear.as b/KalturaRecord/src/gs/easing/Linear.as new file mode 100644 index 0000000..5ebd77d --- /dev/null +++ b/KalturaRecord/src/gs/easing/Linear.as @@ -0,0 +1,16 @@ +package gs.easing { + public class Linear { + public static function easeNone (t:Number, b:Number, c:Number, d:Number):Number { + return c*t/d + b; + } + public static function easeIn (t:Number, b:Number, c:Number, d:Number):Number { + return c*t/d + b; + } + public static function easeOut (t:Number, b:Number, c:Number, d:Number):Number { + return c*t/d + b; + } + public static function easeInOut (t:Number, b:Number, c:Number, d:Number):Number { + return c*t/d + b; + } + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/easing/Quad.as b/KalturaRecord/src/gs/easing/Quad.as new file mode 100644 index 0000000..ec53d09 --- /dev/null +++ b/KalturaRecord/src/gs/easing/Quad.as @@ -0,0 +1,14 @@ +package gs.easing { + public class Quad { + public static function easeIn (t:Number, b:Number, c:Number, d:Number):Number { + return c*(t/=d)*t + b; + } + public static function easeOut (t:Number, b:Number, c:Number, d:Number):Number { + return -c *(t/=d)*(t-2) + b; + } + public static function easeInOut (t:Number, b:Number, c:Number, d:Number):Number { + if ((t/=d/2) < 1) return c/2*t*t + b; + return -c/2 * ((--t)*(t-2) - 1) + b; + } + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/easing/Quart.as b/KalturaRecord/src/gs/easing/Quart.as new file mode 100644 index 0000000..e5ce969 --- /dev/null +++ b/KalturaRecord/src/gs/easing/Quart.as @@ -0,0 +1,14 @@ +package gs.easing { + public class Quart { + public static function easeIn (t:Number, b:Number, c:Number, d:Number):Number { + return c*(t/=d)*t*t*t + b; + } + public static function easeOut (t:Number, b:Number, c:Number, d:Number):Number { + return -c * ((t=t/d-1)*t*t*t - 1) + b; + } + public static function easeInOut (t:Number, b:Number, c:Number, d:Number):Number { + if ((t/=d/2) < 1) return c/2*t*t*t*t + b; + return -c/2 * ((t-=2)*t*t*t - 2) + b; + } + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/easing/Quint.as b/KalturaRecord/src/gs/easing/Quint.as new file mode 100644 index 0000000..497159a --- /dev/null +++ b/KalturaRecord/src/gs/easing/Quint.as @@ -0,0 +1,14 @@ +package gs.easing { + public class Quint { + public static function easeIn (t:Number, b:Number, c:Number, d:Number):Number { + return c*(t/=d)*t*t*t*t + b; + } + public static function easeOut (t:Number, b:Number, c:Number, d:Number):Number { + return c*((t=t/d-1)*t*t*t*t + 1) + b; + } + public static function easeInOut (t:Number, b:Number, c:Number, d:Number):Number { + if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b; + return c/2*((t-=2)*t*t*t*t + 2) + b; + } + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/easing/Sine.as b/KalturaRecord/src/gs/easing/Sine.as new file mode 100644 index 0000000..ffe0db3 --- /dev/null +++ b/KalturaRecord/src/gs/easing/Sine.as @@ -0,0 +1,15 @@ +package gs.easing { + public class Sine { + private static const _HALF_PI:Number = Math.PI / 2; + + public static function easeIn (t:Number, b:Number, c:Number, d:Number):Number { + return -c * Math.cos(t/d * _HALF_PI) + c + b; + } + public static function easeOut (t:Number, b:Number, c:Number, d:Number):Number { + return c * Math.sin(t/d * _HALF_PI) + b; + } + public static function easeInOut (t:Number, b:Number, c:Number, d:Number):Number { + return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b; + } + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/easing/Strong.as b/KalturaRecord/src/gs/easing/Strong.as new file mode 100644 index 0000000..b39a2ad --- /dev/null +++ b/KalturaRecord/src/gs/easing/Strong.as @@ -0,0 +1,14 @@ +package gs.easing { + public class Strong { + public static function easeIn(t:Number, b:Number, c:Number, d:Number):Number { + return c*(t/=d)*t*t*t*t + b; + } + public static function easeOut(t:Number, b:Number, c:Number, d:Number):Number { + return c*((t=t/d-1)*t*t*t*t + 1) + b; + } + public static function easeInOut(t:Number, b:Number, c:Number, d:Number):Number { + if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b; + return c/2*((t-=2)*t*t*t*t + 2) + b; + } + } +} diff --git a/KalturaRecord/src/gs/easing/easing_readme.txt b/KalturaRecord/src/gs/easing/easing_readme.txt new file mode 100644 index 0000000..4b99688 --- /dev/null +++ b/KalturaRecord/src/gs/easing/easing_readme.txt @@ -0,0 +1,21 @@ +This readme file applies to all eases in this directory EXCEPT the CustomEase. + +============================================================================================ + Easing Equations + (c) 2003 Robert Penner, all rights reserved. + This work is subject to the terms in http://www.robertpenner.com/easing_terms_of_use.html. +============================================================================================ + +TERMS OF USE - EASING EQUATIONS + +Open source under the BSD License. + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/KalturaRecord/src/gs/events/TweenEvent.as b/KalturaRecord/src/gs/events/TweenEvent.as new file mode 100644 index 0000000..29167fe --- /dev/null +++ b/KalturaRecord/src/gs/events/TweenEvent.as @@ -0,0 +1,35 @@ +/* +VERSION: 0.9 +DATE: 7/15/2008 +ACTIONSCRIPT VERSION: 3.0 (Requires Flash Player 9) +DESCRIPTION: + Used for Event dispatching from the AS3 version of TweenMax (www.tweenmax.com) + + +CODED BY: Jack Doyle, jack@greensock.com +Copyright 2008, GreenSock (This work is subject to the terms at http://www.greensock.com/terms_of_use.html.) +*/ + +package gs.events { + import flash.events.Event; + + public class TweenEvent extends Event { + public static const version:Number = 0.9; + public static const START:String = "start"; + public static const UPDATE:String = "update"; + public static const COMPLETE:String = "complete"; + + public var info:Object; + + public function TweenEvent($type:String, $info:Object = null, $bubbles:Boolean = false, $cancelable:Boolean = false){ + super($type, $bubbles, $cancelable); + this.info = $info; + } + + public override function clone():Event{ + return new TweenEvent(this.type, this.info, this.bubbles, this.cancelable); + } + + } + +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/plugins/AutoAlphaPlugin.as b/KalturaRecord/src/gs/plugins/AutoAlphaPlugin.as new file mode 100644 index 0000000..96b2295 --- /dev/null +++ b/KalturaRecord/src/gs/plugins/AutoAlphaPlugin.as @@ -0,0 +1,73 @@ +/* +VERSION: 1.0 +DATE: 1/8/2009 +ACTIONSCRIPT VERSION: 3.0 (AS2 version is also available) +UPDATES & MORE DETAILED DOCUMENTATION AT: http://www.TweenMax.com +DESCRIPTION: + Use autoAlpha instead of the alpha property to gain the additional feature of toggling + the "visible" property to false if/when alpha reaches 0. It will also toggle visible + to true before the tween starts if the value of autoAlpha is greater than zero. + +USAGE: + import gs.*; + import gs.plugins.*; + TweenPlugin.activate([AutoAlphaPlugin]); //only do this once in your SWF to activate the plugin (it is already activated in TweenLite and TweenMax by default) + + TweenLite.to(mc, 1, {autoAlpha:0}); + +BYTES ADDED TO SWF: 339 (0.3kb) (not including dependencies) + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs.plugins { + import flash.display.*; + + import gs.*; + + public class AutoAlphaPlugin extends TweenPlugin { + public static const VERSION:Number = 1.0; + public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility + + protected var _tweenVisible:Boolean; + protected var _visible:Boolean; + protected var _tween:TweenLite; + protected var _target:Object; + + public function AutoAlphaPlugin() { + super(); + this.propName = "autoAlpha"; + this.overwriteProps = ["alpha","visible"]; + this.onComplete = onCompleteTween; + } + + override public function onInitTween($target:Object, $value:*, $tween:TweenLite):Boolean { + _target = $target; + _tween = $tween; + _visible = Boolean($value != 0); + _tweenVisible = true; + addTween($target, "alpha", $target.alpha, $value, "alpha"); + return true; + } + + override public function killProps($lookup:Object):void { + super.killProps($lookup); + _tweenVisible = !Boolean("visible" in $lookup); + } + + public function onCompleteTween():void { + if (_tweenVisible && _tween.vars.runBackwards != true && _tween.ease == _tween.vars.ease) { //_tween.ease == _tween.vars.ease checks to make sure the tween wasn't reversed with a TweenGroup + _target.visible = _visible; + } + } + + override public function set changeFactor($n:Number):void { + updateTweens($n); + if (_target.visible != true && _tweenVisible) { + _target.visible = true; + } + } + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/plugins/BevelFilterPlugin.as b/KalturaRecord/src/gs/plugins/BevelFilterPlugin.as new file mode 100644 index 0000000..d7cad27 --- /dev/null +++ b/KalturaRecord/src/gs/plugins/BevelFilterPlugin.as @@ -0,0 +1,62 @@ +/* +VERSION: 1.0 +DATE: 1/8/2009 +ACTIONSCRIPT VERSION: 3.0 (AS2 version is also available) +UPDATES & MORE DETAILED DOCUMENTATION AT: http://www.TweenMax.com +DESCRIPTION: + Tweens a BevelFilter. The following properties are available (you only need to define the ones you want to tween): + - distance : Number [0] + - angle : Number [0] + - highlightColor : uint [0xFFFFFF] + - highlightAlpha : Number [0.5] + - shadowColor : uint [0x000000] + - shadowAlpha :Number [0.5] + - blurX : Number [2] + - blurY : Number [2] + - strength : Number [0] + - quality : uint [2] + - index : uint + - addFilter : Boolean [false] + - remove : Boolean [false] + + Set remove to true if you want the filter to be removed when the tween completes. + +USAGE: + import gs.*; + import gs.plugins.*; + TweenPlugin.activate([BevelFilterPlugin]); //only do this once in your SWF to activate the plugin in TweenLite (it is already activated in TweenMax by default) + + TweenLite.to(mc, 1, {bevelFilter:{blurX:10, blurY:10, distance:6, angle:45, strength:1}}); + + +BYTES ADDED TO SWF: 166 (0.16kb) (not including dependencies) + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs.plugins { + import flash.filters.*; + import flash.display.*; + + import gs.*; + + public class BevelFilterPlugin extends FilterPlugin { + public static const VERSION:Number = 1.0; + public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility + + public function BevelFilterPlugin() { + super(); + this.propName = "bevelFilter"; + this.overwriteProps = ["bevelFilter"]; + } + + override public function onInitTween($target:Object, $value:*, $tween:TweenLite):Boolean { + _target = $target; + _type = BevelFilter; + initFilter($value, new BevelFilter(0, 0, 0xFFFFFF, 0.5, 0x000000, 0.5, 2, 2, 0, $value.quality || 2)); + return true; + } + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/plugins/BezierPlugin.as b/KalturaRecord/src/gs/plugins/BezierPlugin.as new file mode 100644 index 0000000..f5bffe6 --- /dev/null +++ b/KalturaRecord/src/gs/plugins/BezierPlugin.as @@ -0,0 +1,211 @@ +/* +VERSION: 1.01 +DATE: 1/22/2009 +ACTIONSCRIPT VERSION: 3.0 (AS2 version is also available) +UPDATES & MORE DETAILED DOCUMENTATION AT: http://www.TweenMax.com +DESCRIPTION: + Bezier tweening allows you to tween in a non-linear way. For example, you may want to tween + a MovieClip's position from the origin (0,0) 500 pixels to the right (500,0) but curve downwards + through the middle of the tween. Simply pass as many objects in the bezier array as you'd like, + one for each "control point" (see documentation on Flash's curveTo() drawing method for more + about how control points work). + + Keep in mind that you can bezier tween ANY properties, not just x/y. + + Also, if you'd like to rotate the target in the direction of the bezier path, + use the orientToBeizer special property. In order to alter a rotation property accurately, + TweenLite/Max needs 4 pieces of information: + 1) Position property 1 (typically "x") + 2) Position property 2 (typically "y") + 3) Rotational property (typically "rotation") + 4) Number of degrees to add (optional - makes it easy to orient your MovieClip properly) + The orientToBezier property should be an Array containing one Array for each set of these values. + For maximum flexibility, you can pass in any number of arrays inside the container array, one + for each rotational property. This can be convenient when working in 3D because you can rotate + on multiple axis. If you're doing a standard 2D x/y tween on a bezier, you can simply pass + in a boolean value of true and TweenLite/Max will use a typical setup, [["x", "y", "rotation", 0]]. + Hint: Don't forget the container Array (notice the double outer brackets) + + +USAGE: + import gs.*; + import gs.plugins.*; + TweenPlugin.activate([BezierPlugin]); //only do this once in your SWF to activate the plugin in TweenLite (it is already activated in TweenMax by default) + + TweenLite.to(my_mc, 3, {bezier:[{x:250, y:50}, {x:500, y:0}]}); //makes my_mc travel through 250,50 and end up at 500,0. + + +BYTES ADDED TO SWF: 1215 (not including dependencies) + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs.plugins { + import gs.*; + import gs.utils.tween.*; + + public class BezierPlugin extends TweenPlugin { + public static const VERSION:Number = 1.01; + public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility + + protected static const _RAD2DEG:Number = 180 / Math.PI; //precalculate for speed + + protected var _target:Object; + protected var _orientData:Array; + protected var _orient:Boolean; + protected var _future:Object = {}; //used for orientToBezier projections + protected var _beziers:Object; + + public function BezierPlugin() { + super(); + this.propName = "bezier"; //name of the special property that the plugin should intercept/manage + this.overwriteProps = []; //will be populated in init() + } + + override public function onInitTween($target:Object, $value:*, $tween:TweenLite):Boolean { + if (!($value is Array)) { + return false; + } + init($tween, $value as Array, false); + return true; + } + + protected function init($tween:TweenLite, $beziers:Array, $through:Boolean):void { + _target = $tween.target; + if ($tween.exposedVars.orientToBezier == true) { + _orientData = [["x", "y", "rotation", 0]]; + _orient = true; + } else if ($tween.exposedVars.orientToBezier is Array) { + _orientData = $tween.exposedVars.orientToBezier; + _orient = true; + } + var props:Object = {}, i:int, p:String; + for (i = 0; i < $beziers.length; i++) { + for (p in $beziers[i]) { + if (props[p] == undefined) { + props[p] = [$tween.target[p]]; + } + if (typeof($beziers[i][p]) == "number") { + props[p].push($beziers[i][p]); + } else { + props[p].push($tween.target[p] + Number($beziers[i][p])); //relative value + } + } + } + for (p in props) { + this.overwriteProps[this.overwriteProps.length] = p; + if ($tween.exposedVars[p] != undefined) { + if (typeof($tween.exposedVars[p]) == "number") { + props[p].push($tween.exposedVars[p]); + } else { + props[p].push($tween.target[p] + Number($tween.exposedVars[p])); //relative value + } + delete $tween.exposedVars[p]; //prevent TweenLite from creating normal tweens of the bezier properties. + for (i = $tween.tweens.length - 1; i > -1; i--) { + if ($tween.tweens[i].name == p) { + $tween.tweens.splice(i, 1); //delete any normal tweens of the bezier properties. + } + } + } + } + _beziers = parseBeziers(props, $through); + } + + public static function parseBeziers($props:Object, $through:Boolean=false):Object { //$props object should contain a property for each one you'd like bezier paths for. Each property should contain a single Array with the numeric point values (i.e. props.x = [12,50,80] and props.y = [50,97,158]). It'll return a new object with an array of values for each property. The first element in the array is the start value, the second is the control point, and the 3rd is the end value. (i.e. returnObject.x = [[12, 32, 50}, [50, 65, 80]]) + var i:int, a:Array, b:Object, p:String; + var all:Object = {}; + if ($through) { + for (p in $props) { + a = $props[p]; + all[p] = b = []; + if (a.length > 2) { + b[b.length] = [a[0], a[1] - ((a[2] - a[0]) / 4), a[1]]; + for (i = 1; i < a.length - 1; i++) { + b[b.length] = [a[i], a[i] + (a[i] - b[i - 1][1]), a[i + 1]]; + } + } else { + b[b.length] = [a[0], (a[0] + a[1]) / 2, a[1]]; + } + } + } else { + for (p in $props) { + a = $props[p]; + all[p] = b = []; + if (a.length > 3) { + b[b.length] = [a[0], a[1], (a[1] + a[2]) / 2]; + for (i = 2; i < a.length - 2; i++) { + b[b.length] = [b[i - 2][2], a[i], (a[i] + a[i + 1]) / 2]; + } + b[b.length] = [b[b.length - 1][2], a[a.length - 2], a[a.length - 1]]; + } else if (a.length == 3) { + b[b.length] = [a[0], a[1], a[2]]; + } else if (a.length == 2) { + b[b.length] = [a[0], (a[0] + a[1]) / 2, a[1]]; + } + } + } + return all; + } + + override public function killProps($lookup:Object):void { + for (var p:String in _beziers) { + if (p in $lookup) { + delete _beziers[p]; + } + } + super.killProps($lookup); + } + + override public function set changeFactor($n:Number):void { + var i:int, p:String, b:Object, t:Number, segments:uint, val:Number, neg:int; + if ($n == 1) { //to make sure the end values are EXACTLY what they need to be. + for (p in _beziers) { + i = _beziers[p].length - 1; + _target[p] = _beziers[p][i][2]; + } + } else { + for (p in _beziers) { + segments = _beziers[p].length; + if ($n < 0) { + i = 0; + } else if ($n >= 1) { + i = segments - 1; + } else { + i = int(segments * $n); + } + t = ($n - (i * (1 / segments))) * segments; + b = _beziers[p][i]; + if (this.round) { + val = b[0] + t * (2 * (1 - t) * (b[1] - b[0]) + t * (b[2] - b[0])); + neg = (val < 0) ? -1 : 1; + _target[p] = ((val % 1) * neg > 0.5) ? int(val) + neg : int(val); //twice as fast as Math.round() + } else { + _target[p] = b[0] + t * (2 * (1 - t) * (b[1] - b[0]) + t * (b[2] - b[0])); + } + } + } + + if (_orient) { + var oldTarget:Object = _target, oldRound:Boolean = this.round; + _target = _future; + this.round = false; + _orient = false; + this.changeFactor = $n + 0.01; + _target = oldTarget; + this.round = oldRound; + _orient = true; + var dx:Number, dy:Number, cotb:Array, toAdd:Number; + for (i = 0; i < _orientData.length; i++) { + cotb = _orientData[i]; //current orientToBezier Array + toAdd = cotb[3] || 0; + dx = _future[cotb[0]] - _target[cotb[0]]; + dy = _future[cotb[1]] - _target[cotb[1]]; + _target[cotb[2]] = Math.atan2(dy, dx) * _RAD2DEG + toAdd; + } + } + + } + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/plugins/BezierThroughPlugin.as b/KalturaRecord/src/gs/plugins/BezierThroughPlugin.as new file mode 100644 index 0000000..f844bd8 --- /dev/null +++ b/KalturaRecord/src/gs/plugins/BezierThroughPlugin.as @@ -0,0 +1,68 @@ +/* +VERSION: 1.0 +DATE: 1/8/2009 +ACTIONSCRIPT VERSION: 3.0 (AS2 version is also available) +UPDATES & MORE DETAILED DOCUMENTATION AT: http://www.TweenMax.com +DESCRIPTION: + Identical to bezier except that instead of defining bezier control point values, you + define points through which the bezier values should move. This can be more intuitive + than using control points. Simply pass as many objects in the bezier Array as you'd like, + one for each point through which the values should travel. For example, if you want the + curved motion path to travel through the coordinates x:250, y:100 and x:50, y:200 and then + end up at 500, 100, you'd do: + + TweenLite.to(mc, 2, {bezierThrough:[{x:250, y:100}, {x:50, y:200}, {x:500, y:200}]}); + + Keep in mind that you can bezierThrough tween ANY properties, not just x/y. + + Also, if you'd like to rotate the target in the direction of the bezier path, + use the orientToBeizer special property. In order to alter a rotation property accurately, + TweenLite/Max needs 4 pieces of information: + 1) Position property 1 (typically "x") + 2) Position property 2 (typically "y") + 3) Rotational property (typically "rotation") + 4) Number of degrees to add (optional - makes it easy to orient your MovieClip properly) + The orientToBezier property should be an Array containing one Array for each set of these values. + For maximum flexibility, you can pass in any number of arrays inside the container array, one + for each rotational property. This can be convenient when working in 3D because you can rotate + on multiple axis. If you're doing a standard 2D x/y tween on a bezier, you can simply pass + in a boolean value of true and TweenLite/Max will use a typical setup, [["x", "y", "rotation", 0]]. + Hint: Don't forget the container Array (notice the double outer brackets) + + +USAGE: + import gs.*; + import gs.plugins.*; + TweenPlugin.activate([BezierThroughPlugin]); //only do this once in your SWF to activate the plugin in TweenLite (it is already activated in TweenMax by default) + + TweenLite.to(mc, 2, {bezierThrough:[{x:250, y:100}, {x:50, y:200}, {x:500, y:200}]}); + +BYTES ADDED TO SWF: 116 (not including dependencies) + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs.plugins { + import gs.*; + + public class BezierThroughPlugin extends BezierPlugin { + public static const VERSION:Number = 1.0; + public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility + + public function BezierThroughPlugin() { + super(); + this.propName = "bezierThrough"; //name of the special property that the plugin should intercept/manage + } + + override public function onInitTween($target:Object, $value:*, $tween:TweenLite):Boolean { + if (!($value is Array)) { + return false; + } + init($tween, $value as Array, true); + return true; + } + + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/plugins/BlurFilterPlugin.as b/KalturaRecord/src/gs/plugins/BlurFilterPlugin.as new file mode 100644 index 0000000..447f7cf --- /dev/null +++ b/KalturaRecord/src/gs/plugins/BlurFilterPlugin.as @@ -0,0 +1,54 @@ +/* +VERSION: 1.0 +DATE: 1/8/2009 +ACTIONSCRIPT VERSION: 3.0 (AS2 version is also available) +UPDATES & MORE DETAILED DOCUMENTATION AT: http://www.TweenMax.com +DESCRIPTION: + Tweens a BlurFilter. The following properties are available (you only need to define the ones you want to tween): + - blurX : Number [0] + - blurY : Number [0] + - quality : uint [2] + - index : uint + - addFilter : Boolean [false] + - remove : Boolean [false] + + Set remove to true if you want the filter to be removed when the tween completes. + +USAGE: + import gs.*; + import gs.plugins.*; + TweenPlugin.activate([BlurFilterPlugin]); //only do this once in your SWF to activate the plugin in TweenLite (it is already activated in TweenMax by default) + + TweenLite.to(mc, 1, {blurFilter:{blurX:10, blurY:10}}); + + +BYTES ADDED TO SWF: 156 (not including dependencies) + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs.plugins { + import flash.filters.*; + import flash.display.*; + import gs.*; + + public class BlurFilterPlugin extends FilterPlugin { + public static const VERSION:Number = 1.0; + public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility + + public function BlurFilterPlugin() { + super(); + this.propName = "blurFilter"; + this.overwriteProps = ["blurFilter"]; + } + + override public function onInitTween($target:Object, $value:*, $tween:TweenLite):Boolean { + _target = $target; + _type = BlurFilter; + initFilter($value, new BlurFilter(0, 0, $value.quality || 2)); + return true; + } + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/plugins/ColorMatrixFilterPlugin.as b/KalturaRecord/src/gs/plugins/ColorMatrixFilterPlugin.as new file mode 100644 index 0000000..5d5c16b --- /dev/null +++ b/KalturaRecord/src/gs/plugins/ColorMatrixFilterPlugin.as @@ -0,0 +1,218 @@ +/* +VERSION: 1.1 +DATE: 3/20/2009 +ACTIONSCRIPT VERSION: 3.0 (AS2 version is also available) +UPDATES & MORE DETAILED DOCUMENTATION AT: http://www.TweenMax.com +DESCRIPTION: + ColorMatrixFilter tweening offers an easy way to tween a DisplayObject's saturation, hue, contrast, + brightness, and colorization. The following properties are available (you only need to define the ones you want to tween): + + - colorize : uint (colorizing a DisplayObject makes it look as though you're seeing it through a colored piece of glass whereas tinting it makes every pixel exactly that color. You can control the amount of colorization using the "amount" value where 1 is full strength, 0.5 is half-strength, and 0 has no colorization effect.) + - amount : Number [1] (only used in conjunction with "colorize") + - contrast : Number (1 is normal contrast, 0 has no contrast, and 2 is double the normal contrast, etc.) + - saturation : Number (1 is normal saturation, 0 makes the DisplayObject look black & white, and 2 would be double the normal saturation) + - hue : Number (changes the hue of every pixel. Think of it as degrees, so 180 would be rotating the hue to be exactly opposite as normal, 360 would be the same as 0, etc.) + - brightness : Number (1 is normal brightness, 0 is much darker than normal, and 2 is twice the normal brightness, etc.) + - threshold : Number (number from 0 to 255 that controls the threshold of where the pixels turn white or black) + - matrix : Array (If you already have a matrix from a ColorMatrixFilter that you want to tween to, pass it in with the "matrix" property. This makes it possible to match effects created in the Flash IDE.) + - index : Number (only necessary if you already have a filter applied and you want to target it with the tween.) + - addFilter : Boolean [false] + - remove : Boolean [false] (Set remove to true if you want the filter to be removed when the tween completes.) + + HINT: If you'd like to match the ColorMatrixFilter values you created in the Flash IDE on a particular object, you can get its matrix like this: + + import flash.display.*; + import flash.filters.*; + + function getColorMatrix($mc:DisplayObject):Array { + var f:Array = $mc.filters, i:uint; + for (i = 0; i < f.length; i++) { + if (f[i] is ColorMatrixFilter) { + return f[i].matrix; + } + } + return null; + } + + var myOriginalMatrix:Array = getColorMatrix(my_mc); //store it so you can tween back to it anytime like TweenMax.to(my_mc, 1, {colorMatrixFilter:{matrix:myOriginalMatrix}}); + + +USAGE: + import gs.*; + import gs.plugins.*; + TweenPlugin.activate([ColorMatrixFilterPlugin]); //only do this once in your SWF to activate the plugin in TweenLite (it is already activated in TweenMax by default) + + TweenLite.to(mc, 1, {colorMatrixFilter:{colorize:0xFF0000}}); + + +BYTES ADDED TO SWF: 1447 (not including dependencies) + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs.plugins { + import flash.display.*; + import flash.filters.*; + + import gs.*; + + public class ColorMatrixFilterPlugin extends FilterPlugin { + public static const VERSION:Number = 1.1; + public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility + + protected static var _idMatrix:Array = [1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0]; + protected static var _lumR:Number = 0.212671; //Red constant - used for a few color matrix filter functions + protected static var _lumG:Number = 0.715160; //Green constant - used for a few color matrix filter functions + protected static var _lumB:Number = 0.072169; //Blue constant - used for a few color matrix filter functions + + protected var _matrix:Array; + protected var _matrixTween:EndArrayPlugin; + + public function ColorMatrixFilterPlugin() { + super(); + this.propName = "colorMatrixFilter"; + this.overwriteProps = ["colorMatrixFilter"]; + } + + override public function onInitTween($target:Object, $value:*, $tween:TweenLite):Boolean { + _target = $target; + _type = ColorMatrixFilter; + var cmf:Object = $value; + initFilter({remove:$value.remove, index:$value.index, addFilter:$value.addFilter}, new ColorMatrixFilter(_idMatrix.slice())); + _matrix = ColorMatrixFilter(_filter).matrix; + var endMatrix:Array = []; + if (cmf.matrix != null && (cmf.matrix is Array)) { + endMatrix = cmf.matrix; + } else { + if (cmf.relative == true) { + endMatrix = _matrix.slice(); + } else { + endMatrix = _idMatrix.slice(); + } + endMatrix = setBrightness(endMatrix, cmf.brightness); + endMatrix = setContrast(endMatrix, cmf.contrast); + endMatrix = setHue(endMatrix, cmf.hue); + endMatrix = setSaturation(endMatrix, cmf.saturation); + endMatrix = setThreshold(endMatrix, cmf.threshold); + if (!isNaN(cmf.colorize)) { + endMatrix = colorize(endMatrix, cmf.colorize, cmf.amount); + } + } + _matrixTween = new EndArrayPlugin(); + _matrixTween.init(_matrix, endMatrix); + return true; + } + + override public function set changeFactor($n:Number):void { + _matrixTween.changeFactor = $n; + ColorMatrixFilter(_filter).matrix = _matrix; + super.changeFactor = $n; + } + + +//---- MATRIX OPERATIONS -------------------------------------------------------------------------------- + + public static function colorize($m:Array, $color:Number, $amount:Number = 1):Array { + if (isNaN($color)) { + return $m; + } else if (isNaN($amount)) { + $amount = 1; + } + var r:Number = (($color >> 16) & 0xff) / 255; + var g:Number = (($color >> 8) & 0xff) / 255; + var b:Number = ($color & 0xff) / 255; + var inv:Number = 1 - $amount; + var temp:Array = [inv + $amount * r * _lumR, $amount * r * _lumG, $amount * r * _lumB, 0, 0, + $amount * g * _lumR, inv + $amount * g * _lumG, $amount * g * _lumB, 0, 0, + $amount * b * _lumR, $amount * b * _lumG, inv + $amount * b * _lumB, 0, 0, + 0, 0, 0, 1, 0]; + return applyMatrix(temp, $m); + } + + public static function setThreshold($m:Array, $n:Number):Array { + if (isNaN($n)) { + return $m; + } + var temp:Array = [_lumR * 256, _lumG * 256, _lumB * 256, 0, -256 * $n, + _lumR * 256, _lumG * 256, _lumB * 256, 0, -256 * $n, + _lumR * 256, _lumG * 256, _lumB * 256, 0, -256 * $n, + 0, 0, 0, 1, 0]; + return applyMatrix(temp, $m); + } + + public static function setHue($m:Array, $n:Number):Array { + if (isNaN($n)) { + return $m; + } + $n *= Math.PI / 180; + var c:Number = Math.cos($n); + var s:Number = Math.sin($n); + var temp:Array = [(_lumR + (c * (1 - _lumR))) + (s * (-_lumR)), (_lumG + (c * (-_lumG))) + (s * (-_lumG)), (_lumB + (c * (-_lumB))) + (s * (1 - _lumB)), 0, 0, (_lumR + (c * (-_lumR))) + (s * 0.143), (_lumG + (c * (1 - _lumG))) + (s * 0.14), (_lumB + (c * (-_lumB))) + (s * -0.283), 0, 0, (_lumR + (c * (-_lumR))) + (s * (-(1 - _lumR))), (_lumG + (c * (-_lumG))) + (s * _lumG), (_lumB + (c * (1 - _lumB))) + (s * _lumB), 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1]; + return applyMatrix(temp, $m); + } + + public static function setBrightness($m:Array, $n:Number):Array { + if (isNaN($n)) { + return $m; + } + $n = ($n * 100) - 100; + return applyMatrix([1,0,0,0,$n, + 0,1,0,0,$n, + 0,0,1,0,$n, + 0,0,0,1,0, + 0,0,0,0,1], $m); + } + + public static function setSaturation($m:Array, $n:Number):Array { + if (isNaN($n)) { + return $m; + } + var inv:Number = 1 - $n; + var r:Number = inv * _lumR; + var g:Number = inv * _lumG; + var b:Number = inv * _lumB; + var temp:Array = [r + $n, g , b , 0, 0, + r , g + $n, b , 0, 0, + r , g , b + $n, 0, 0, + 0 , 0 , 0 , 1, 0]; + return applyMatrix(temp, $m); + } + + public static function setContrast($m:Array, $n:Number):Array { + if (isNaN($n)) { + return $m; + } + $n += 0.01; + var temp:Array = [$n,0,0,0,128 * (1 - $n), + 0,$n,0,0,128 * (1 - $n), + 0,0,$n,0,128 * (1 - $n), + 0,0,0,1,0]; + return applyMatrix(temp, $m); + } + + public static function applyMatrix($m:Array, $m2:Array):Array { + if (!($m is Array) || !($m2 is Array)) { + return $m2; + } + var temp:Array = [], i:int = 0, z:int = 0, y:int, x:int; + for (y = 0; y < 4; y++) { + for (x = 0; x < 5; x++) { + if (x == 4) { + z = $m[i + 4]; + } else { + z = 0; + } + temp[i + x] = $m[i] * $m2[x] + + $m[i+1] * $m2[x + 5] + + $m[i+2] * $m2[x + 10] + + $m[i+3] * $m2[x + 15] + + z; + } + i += 5; + } + return temp; + } + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/plugins/ColorTransformPlugin.as b/KalturaRecord/src/gs/plugins/ColorTransformPlugin.as new file mode 100644 index 0000000..58dc9a7 --- /dev/null +++ b/KalturaRecord/src/gs/plugins/ColorTransformPlugin.as @@ -0,0 +1,100 @@ +/* +VERSION: 1.01 +DATE: 1/29/2009 +ACTIONSCRIPT VERSION: 3.0 (AS2 version is also available) +UPDATES & MORE DETAILED DOCUMENTATION AT: http://www.TweenMax.com +DESCRIPTION: + Ever wanted to tween ColorTransform properties of a DisplayObject to do advanced effects like overexposing, altering + the brightness or setting the percent/amount of tint? Or maybe you wanted to tween individual ColorTransform + properties like redMultiplier, redOffset, blueMultiplier, blueOffset, etc. This class gives you an easy way to + do just that. + + PROPERTIES: + - tint (or color) : uint - Color of the tint. Use a hex value, like 0xFF0000 for red. + - tintAmount : Number - Number between 0 and 1. Works with the "tint" property and indicats how much of an effect the tint should have. 0 makes the tint invisible, 0.5 is halfway tinted, and 1 is completely tinted. + - brightness : Number - Number between 0 and 2 where 1 is normal brightness, 0 is completely dark/black, and 2 is completely bright/white + - exposure : Number - Number between 0 and 2 where 1 is normal exposure, 0, is completely underexposed, and 2 is completely overexposed. Overexposing an object is different then changing the brightness - it seems to almost bleach the image and looks more dynamic and interesting (subjectively speaking). + - redOffset : Number + - greenOffset : Number + - blueOffset : Number + - alphaOffset : Number + - redMultiplier : Number + - greenMultiplier : Number + - blueMultiplier : Number + - alphaMultiplier : Number + +USAGE: + import gs.*; + import gs.plugins.*; + TweenPlugin.activate([ColorTransformPlugin]); //only do this once in your SWF to activate the plugin (it is already activated in TweenLite and TweenMax by default) + + TweenLite.to(mc, 1, {colorTransform:{tint:0xFF0000, tintAmount:0.5}); + + +BYTES ADDED TO SWF: 371 (not including dependencies) + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs.plugins { + import flash.display.*; + import flash.geom.ColorTransform; + + import gs.*; + + public class ColorTransformPlugin extends TintPlugin { + public static const VERSION:Number = 1.01; + public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility + + public function ColorTransformPlugin() { + super(); + this.propName = "colorTransform"; + } + + override public function onInitTween($target:Object, $value:*, $tween:TweenLite):Boolean { + if (!($target is DisplayObject)) { + return false; + } + var end:ColorTransform = $target.transform.colorTransform; + if ($value.isTV == true) { + $value = $value.exposedVars; //for compatibility with TweenLiteVars and TweenMaxVars + } + for (var p:String in $value) { + if (p == "tint" || p == "color") { + if ($value[p] != null) { + end.color = int($value[p]); + } + } else if (p == "tintAmount" || p == "exposure" || p == "brightness") { + //handle this later... + } else { + end[p] = $value[p]; + } + } + + if (!isNaN($value.tintAmount)) { + var ratio:Number = $value.tintAmount / (1 - ((end.redMultiplier + end.greenMultiplier + end.blueMultiplier) / 3)); + end.redOffset *= ratio; + end.greenOffset *= ratio; + end.blueOffset *= ratio; + end.redMultiplier = end.greenMultiplier = end.blueMultiplier = 1 - $value.tintAmount; + } else if (!isNaN($value.exposure)) { + end.redOffset = end.greenOffset = end.blueOffset = 255 * ($value.exposure - 1); + end.redMultiplier = end.greenMultiplier = end.blueMultiplier = 1; + } else if (!isNaN($value.brightness)) { + end.redOffset = end.greenOffset = end.blueOffset = Math.max(0, ($value.brightness - 1) * 255); + end.redMultiplier = end.greenMultiplier = end.blueMultiplier = 1 - Math.abs($value.brightness - 1); + } + + if ($tween.exposedVars.alpha != undefined && $value.alphaMultiplier == undefined) { + end.alphaMultiplier = $tween.exposedVars.alpha; + $tween.killVars({alpha:1}); + } + + init($target as DisplayObject, end); + + return true; + } + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/plugins/DropShadowFilterPlugin.as b/KalturaRecord/src/gs/plugins/DropShadowFilterPlugin.as new file mode 100644 index 0000000..82dea72 --- /dev/null +++ b/KalturaRecord/src/gs/plugins/DropShadowFilterPlugin.as @@ -0,0 +1,63 @@ +/* +VERSION: 1.0 +DATE: 1/8/2009 +ACTIONSCRIPT VERSION: 3.0 (AS2 version is also available) +UPDATES & MORE DETAILED DOCUMENTATION AT: http://www.TweenMax.com +DESCRIPTION: + Tweens a DropShadowFilter. The following properties are available (you only need to define the ones you want to tween): + + - distance : Number [0] + - angle : Number [45] + - color : uint [0x000000] + - alpha :Number [0] + - blurX : Number [0] + - blurY : Number [0] + - strength : Number [1] + - quality : uint [2] + - inner : Boolean [false] + - knockout : Boolean [false] + - hideObject : Boolean [false] + - index : uint + - addFilter : Boolean [false] + - remove : Boolean [false] + + Set remove to true if you want the filter to be removed when the tween completes. + +USAGE: + import gs.*; + import gs.plugins.*; + TweenPlugin.activate([DropShadowFilterPlugin]); //only do this once in your SWF to activate the plugin in TweenLite (it is already activated in TweenMax by default) + + TweenLite.to(mc, 1, {dropShadowFilter:{blurX:5, blurY:5, distance:5, alpha:0.6}}); + + +BYTES ADDED TO SWF: 184 (not including dependencies) + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs.plugins { + import flash.filters.*; + import flash.display.*; + import gs.*; + + public class DropShadowFilterPlugin extends FilterPlugin { + public static const VERSION:Number = 1.0; + public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility + + public function DropShadowFilterPlugin() { + super(); + this.propName = "dropShadowFilter"; + this.overwriteProps = ["dropShadowFilter"]; + } + + override public function onInitTween($target:Object, $value:*, $tween:TweenLite):Boolean { + _target = $target; + _type = DropShadowFilter; + initFilter($value, new DropShadowFilter(0, 45, 0x000000, 0, 0, 0, 1, $value.quality || 2, $value.inner, $value.knockout, $value.hideObject)); + return true; + } + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/plugins/EndArrayPlugin.as b/KalturaRecord/src/gs/plugins/EndArrayPlugin.as new file mode 100644 index 0000000..5a2cef0 --- /dev/null +++ b/KalturaRecord/src/gs/plugins/EndArrayPlugin.as @@ -0,0 +1,80 @@ +/* +VERSION: 1.01 +DATE: 1/10/2009 +ACTIONSCRIPT VERSION: 3.0 (AS2 version is also available) +UPDATES & MORE DETAILED DOCUMENTATION AT: http://www.TweenMax.com +DESCRIPTION: + Tweens numbers in an Array. + +USAGE: + import gs.*; + import gs.plugins.*; + TweenPlugin.activate([EndArrayPlugin]); //only do this once in your SWF to activate the plugin (it is already activated in TweenLite and TweenMax by default) + + var myArray:Array = [1,2,3,4]; + TweenMax.to(myArray, 1.5, {endArray:[10,20,30,40]}); + + +BYTES ADDED TO SWF: 278 (not including dependencies) + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs.plugins { + import flash.display.*; + + import gs.*; + import gs.utils.tween.*; + + public class EndArrayPlugin extends TweenPlugin { + public static const VERSION:Number = 1.01; + public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility + + protected var _a:Array; + protected var _info:Array = []; + + public function EndArrayPlugin() { + super(); + this.propName = "endArray"; //name of the special property that the plugin should intercept/manage + this.overwriteProps = ["endArray"]; + } + + override public function onInitTween($target:Object, $value:*, $tween:TweenLite):Boolean { + if (!($target is Array) || !($value is Array)) { + return false; + } + init($target as Array, $value); + return true; + } + + public function init($start:Array, $end:Array):void { + _a = $start; + for (var i:int = $end.length - 1; i > -1; i--) { + if ($start[i] != $end[i] && $start[i] != null) { + _info[_info.length] = new ArrayTweenInfo(i, _a[i], $end[i] - _a[i]); + } + } + } + + override public function set changeFactor($n:Number):void { + var i:int, ti:ArrayTweenInfo; + if (this.round) { + var val:Number, neg:int; + for (i = _info.length - 1; i > -1; i--) { + ti = _info[i]; + val = ti.start + (ti.change * $n); + neg = (val < 0) ? -1 : 1; + _a[ti.index] = ((val % 1) * neg > 0.5) ? int(val) + neg : int(val); //twice as fast as Math.round() + } + } else { + for (i = _info.length - 1; i > -1; i--) { + ti = _info[i]; + _a[ti.index] = ti.start + (ti.change * $n); + } + } + } + + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/plugins/FastTransformPlugin.as b/KalturaRecord/src/gs/plugins/FastTransformPlugin.as new file mode 100644 index 0000000..7931f71 --- /dev/null +++ b/KalturaRecord/src/gs/plugins/FastTransformPlugin.as @@ -0,0 +1,129 @@ +/* +VERSION: 1.02 +DATE: 2/8/2009 +ACTIONSCRIPT VERSION: 3.0 +UPDATES & MORE DETAILED DOCUMENTATION AT: http://www.TweenMax.com +DESCRIPTION: + Slightly faster way to change a DisplayObject's x, y, width, height, scaleX, scaleY, and/or rotation value(s). You'd likely + only see a difference if/when tweening very large quantities of objects. + +USAGE: + import gs.*; + import gs.plugins.*; + TweenPlugin.activate([FastTransformPlugin]); //only do this once in your SWF to activate the plugin + + TweenLite.to(mc, 1, {fastTransform:{x:50, y:300, width:200, height:30}}); + + + + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs.plugins { + import flash.display.*; + + import gs.*; + + public class FastTransformPlugin extends TweenPlugin { + public static const VERSION:Number = 1.02; + public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility + + protected var _target:DisplayObject; + protected var xStart:Number; + protected var xChange:Number = 0; + protected var yStart:Number; + protected var yChange:Number = 0; + protected var widthStart:Number; + protected var widthChange:Number = 0; + protected var heightStart:Number; + protected var heightChange:Number = 0; + protected var scaleXStart:Number; + protected var scaleXChange:Number = 0; + protected var scaleYStart:Number; + protected var scaleYChange:Number = 0; + protected var rotationStart:Number; + protected var rotationChange:Number = 0; + + + public function FastTransformPlugin() { + super(); + this.propName = "fastTransform"; + this.overwriteProps = []; + } + override public function onInitTween($target:Object, $value:*, $tween:TweenLite):Boolean { + _target = $target as DisplayObject; + if ("x" in $value) { + xStart = _target.x; + xChange = (typeof($value.x) == "number") ? $value.x - _target.x : Number($value.x); + this.overwriteProps[this.overwriteProps.length] = "x"; + } + if ("y" in $value) { + yStart = _target.y; + yChange = (typeof($value.y) == "number") ? $value.y - _target.y : Number($value.y); + this.overwriteProps[this.overwriteProps.length] = "y"; + } + if ("width" in $value) { + widthStart = _target.width; + widthChange = (typeof($value.width) == "number") ? $value.width - _target.width : Number($value.width); + this.overwriteProps[this.overwriteProps.length] = "width"; + } + if ("height" in $value) { + heightStart = _target.height; + heightChange = (typeof($value.height) == "number") ? $value.height - _target.height : Number($value.height); + this.overwriteProps[this.overwriteProps.length] = "height"; + } + if ("scaleX" in $value) { + scaleXStart = _target.scaleX; + scaleXChange = (typeof($value.scaleX) == "number") ? $value.scaleX - _target.scaleX : Number($value.scaleX); + this.overwriteProps[this.overwriteProps.length] = "scaleX"; + } + if ("scaleY" in $value) { + scaleYStart = _target.scaleY; + scaleYChange = (typeof($value.scaleY) == "number") ? $value.scaleY - _target.scaleY : Number($value.scaleY); + this.overwriteProps[this.overwriteProps.length] = "scaleY"; + } + if ("rotation" in $value) { + rotationStart = _target.rotation; + rotationChange = (typeof($value.rotation) == "number") ? $value.rotation - _target.rotation : Number($value.rotation); + this.overwriteProps[this.overwriteProps.length] = "rotation"; + } + return true; + } + + override public function killProps($lookup:Object):void { + for (var p:String in $lookup) { + if (p + "Change" in this && !isNaN(this[p + "Change"])) { + this[p + "Change"] = 0; + } + } + super.killProps($lookup); + } + + override public function set changeFactor($n:Number):void { + if (xChange != 0) { + _target.x = xStart + ($n * xChange); + } + if (yChange != 0) { + _target.y = yStart + ($n * yChange); + } + if (widthChange != 0) { + _target.width = widthStart + ($n * widthChange); + } + if (heightChange != 0) { + _target.height = heightStart + ($n * heightChange); + } + if (scaleXChange != 0) { + _target.scaleX = scaleXStart + ($n * scaleXChange); + } + if (scaleYChange != 0) { + _target.scaleY = scaleYStart + ($n * scaleYChange); + } + if (rotationChange != 0) { + _target.rotation = rotationStart + ($n * rotationChange); + } + } + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/plugins/FilterPlugin.as b/KalturaRecord/src/gs/plugins/FilterPlugin.as new file mode 100644 index 0000000..cf097bd --- /dev/null +++ b/KalturaRecord/src/gs/plugins/FilterPlugin.as @@ -0,0 +1,120 @@ +/* +VERSION: 1.03 +DATE: 1/24/2009 +ACTIONSCRIPT VERSION: 3.0 (AS2 version is also available) +UPDATES & MORE DETAILED DOCUMENTATION AT: http://www.TweenMax.com +DESCRIPTION: + Base class for all filter plugins (like BlurFilter, colorMatrixFilter, etc.). Handles common routines. + +USAGE: + filter plugins extend this class. + + +BYTES ADDED TO SWF: 672 (1kb) (not including dependencies) + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs.plugins { + import flash.display.*; + import flash.filters.*; + + import gs.*; + import gs.utils.tween.TweenInfo; + + public class FilterPlugin extends TweenPlugin { + public static const VERSION:Number = 1.03; + public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility + + protected var _target:Object; + protected var _type:Class; + protected var _filter:BitmapFilter; + protected var _index:int; + protected var _remove:Boolean; + + public function FilterPlugin() { + super(); + } + + protected function initFilter($props:Object, $default:BitmapFilter):void { + var filters:Array = _target.filters, p:String, i:int, colorTween:HexColorsPlugin; + _index = -1; + if ($props.index != null) { + _index = $props.index; + } else { + for (i = filters.length - 1; i > -1; i--) { + if (filters[i] is _type) { + _index = i; + break; + } + } + } + if (_index == -1 || filters[_index] == null || $props.addFilter == true) { + _index = ($props.index != null) ? $props.index : filters.length; + filters[_index] = $default; + _target.filters = filters; + } + _filter = filters[_index]; + + _remove = Boolean($props.remove == true); + if (_remove) { + this.onComplete = onCompleteTween; + } + var props:Object = ($props.isTV == true) ? $props.exposedVars : $props; //accommodates TweenLiteVars and TweenMaxVars + for (p in props) { + if (!(p in _filter) || _filter[p] == props[p] || p == "remove" || p == "index" || p == "addFilter") { + //ignore + } else { + if (p == "color" || p == "highlightColor" || p == "shadowColor") { + colorTween = new HexColorsPlugin(); + colorTween.initColor(_filter, p, _filter[p], props[p]); + _tweens[_tweens.length] = new TweenInfo(colorTween, "changeFactor", 0, 1, p, false); + } else if (p == "quality" || p == "inner" || p == "knockout" || p == "hideObject") { + _filter[p] = props[p]; + } else { + addTween(_filter, p, _filter[p], props[p], p); + } + } + } + } + + public function onCompleteTween():void { + if (_remove) { + var i:int, filters:Array = _target.filters; + if (!(filters[_index] is _type)) { //a filter may have been added or removed since the tween began, changing the index. + for (i = filters.length - 1; i > -1; i--) { + if (filters[i] is _type) { + filters.splice(i, 1); + break; + } + } + } else { + filters.splice(_index, 1); + } + _target.filters = filters; + } + } + + override public function set changeFactor($n:Number):void { + var i:int, ti:TweenInfo, filters:Array = _target.filters; + for (i = _tweens.length - 1; i > -1; i--) { + ti = _tweens[i]; + ti.target[ti.property] = ti.start + (ti.change * $n); + } + + if (!(filters[_index] is _type)) { //a filter may have been added or removed since the tween began, changing the index. + _index = filters.length - 1; //default (in case it was removed) + for (i = filters.length - 1; i > -1; i--) { + if (filters[i] is _type) { + _index = i; + break; + } + } + } + filters[_index] = _filter; + _target.filters = filters; + } + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/plugins/FrameLabelPlugin.as b/KalturaRecord/src/gs/plugins/FrameLabelPlugin.as new file mode 100644 index 0000000..0d667f9 --- /dev/null +++ b/KalturaRecord/src/gs/plugins/FrameLabelPlugin.as @@ -0,0 +1,58 @@ +/* +VERSION: 1.01 +DATE: 2/23/2009 +ACTIONSCRIPT VERSION: 3.0 (AS2 version is also available) +UPDATES & MORE DETAILED DOCUMENTATION AT: http://www.TweenMax.com +DESCRIPTION: + Tweens a MovieClip to a particular frame label + +USAGE: + import gs.*; + import gs.plugins.*; + TweenPlugin.activate([FrameLabelPlugin]); //only do this once in your SWF to activate the plugin in TweenLite (it is already activated in TweenMax by default) + + TweenLite.to(mc, 1, {frameLabel:"myLabel"}); + + +BYTES ADDED TO SWF: 222 (not including dependencies) + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs.plugins { + import flash.display.*; + import gs.*; + import gs.plugins.*; + + public class FrameLabelPlugin extends FramePlugin { + public static const VERSION:Number = 1.01; + public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility + + public function FrameLabelPlugin() { + super(); + this.propName = "frameLabel"; + } + + override public function onInitTween($target:Object, $value:*, $tween:TweenLite):Boolean { + if (!$tween.target is MovieClip) { + return false; + } + _target = $target as MovieClip; + this.frame = _target.currentFrame; + var labels:Array = _target.currentLabels, label:String = $value, endFrame:int = _target.currentFrame, i:int; + for (i = labels.length - 1; i > -1; i--) { + if (labels[i].name == label) { + endFrame = labels[i].frame; + break; + } + } + if (this.frame != endFrame) { + addTween(this, "frame", this.frame, endFrame, "frame"); + } + return true; + } + + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/plugins/FramePlugin.as b/KalturaRecord/src/gs/plugins/FramePlugin.as new file mode 100644 index 0000000..2ce4752 --- /dev/null +++ b/KalturaRecord/src/gs/plugins/FramePlugin.as @@ -0,0 +1,58 @@ +/* +VERSION: 1.01 +DATE: 2/23/2009 +ACTIONSCRIPT VERSION: 3.0 (AS2 version is also available) +UPDATES & MORE DETAILED DOCUMENTATION AT: http://www.TweenMax.com +DESCRIPTION: + Tweens a MovieClip to a particular frame number + +USAGE: + import gs.*; + import gs.plugins.*; + TweenPlugin.activate([FrameLabelPlugin]); //only do this once in your SWF to activate the plugin (it is already activated in TweenLite and TweenMax by default) + + TweenLite.to(mc, 1, {frame:125}); + + +BYTES ADDED TO SWF: 218 (not including dependencies) + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs.plugins { + import flash.display.*; + import gs.*; + + public class FramePlugin extends TweenPlugin { + public static const VERSION:Number = 1.01; + public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility + + public var frame:int; + protected var _target:MovieClip; + + public function FramePlugin() { + super(); + this.propName = "frame"; + this.overwriteProps = ["frame"]; + this.round = true; + } + + override public function onInitTween($target:Object, $value:*, $tween:TweenLite):Boolean { + if (!($target is MovieClip) || isNaN($value)) { + return false; + } + _target = $target as MovieClip; + this.frame = _target.currentFrame; + addTween(this, "frame", this.frame, $value, "frame"); + return true; + } + + override public function set changeFactor($n:Number):void { + updateTweens($n); + _target.gotoAndStop(this.frame); + } + + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/plugins/GlowFilterPlugin.as b/KalturaRecord/src/gs/plugins/GlowFilterPlugin.as new file mode 100644 index 0000000..bb38a89 --- /dev/null +++ b/KalturaRecord/src/gs/plugins/GlowFilterPlugin.as @@ -0,0 +1,59 @@ +/* +VERSION: 1.0 +DATE: 1/8/2009 +ACTIONSCRIPT VERSION: 3.0 (AS2 version is also available) +UPDATES & MORE DETAILED DOCUMENTATION AT: http://www.TweenMax.com +DESCRIPTION: + Tweens a GlowFilter. The following properties are available (you only need to define the ones you want to tween): + - color : uint [0x000000] + - alpha :Number [0] + - blurX : Number [0] + - blurY : Number [0] + - strength : Number [1] + - quality : uint [2] + - inner : Boolean [false] + - knockout : Boolean [false] + - index : uint + - addFilter : Boolean [false] + - remove : Boolean [false] + + Set remove to true if you want the filter to be removed when the tween completes. + +USAGE: + import gs.*; + import gs.plugins.*; + TweenPlugin.activate([GlowFilterPlugin]); //only do this once in your SWF to activate the plugin in TweenLite (it is already activated in TweenMax by default) + + TweenLite.to(mc, 1, {glowFilter:{color:0x00FF00, blurX:10, blurY:10, strength:1, strength:1}}); + + +BYTES ADDED TO SWF: 187 (not including dependencies) + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs.plugins { + import flash.filters.*; + import flash.display.*; + import gs.*; + + public class GlowFilterPlugin extends FilterPlugin { + public static const VERSION:Number = 1.0; + public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility + + public function GlowFilterPlugin() { + super(); + this.propName = "glowFilter"; + this.overwriteProps = ["glowFilter"]; + } + + override public function onInitTween($target:Object, $value:*, $tween:TweenLite):Boolean { + _target = $target; + _type = GlowFilter; + initFilter($value, new GlowFilter(0xFFFFFF, 0, 0, 0, $value.strength || 1, $value.quality || 2, $value.inner, $value.knockout)); + return true; + } + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/plugins/HexColorsPlugin.as b/KalturaRecord/src/gs/plugins/HexColorsPlugin.as new file mode 100644 index 0000000..8f4951f --- /dev/null +++ b/KalturaRecord/src/gs/plugins/HexColorsPlugin.as @@ -0,0 +1,104 @@ +/* +VERSION: 1.01 +DATE: 2/5/2009 +ACTIONSCRIPT VERSION: 3.0 (AS2 version is also available) +UPDATES & MORE DETAILED DOCUMENTATION AT: http://www.TweenMax.com +DESCRIPTION: + Although hex colors are technically numbers, if you try to tween them conventionally, + you'll notice that they don't tween smoothly. To tween them properly, the red, green, and + blue components must be extracted and tweened independently. The HexColorsPlugin makes it easy. + To tween a property of your object that's a hex color to another hex color, just pass a hexColors + Object with properties named the same as your object's hex color properties. For example, + if myObject has a "myHexColor" property that you'd like to tween to red (0xFF0000) over the + course of 2 seconds, you'd do: + + TweenMax.to(myObject, 2, {hexColors:{myHexColor:0xFF0000}}); + + You can pass in any number of hexColor properties. + +USAGE: + import gs.*; + import gs.plugins.*; + TweenPlugin.activate([HexColorsPlugin]); //only do this once in your SWF to activate the plugin in TweenLite (it is already activated in TweenMax by default) + + TweenLite.to(myObject, 2, {hexColors:{myHexColor:0xFF0000}}); + + or if you just want to tween a color and apply it somewhere on every frame, you could do: + + var myColor:Object = {hex:0xFF0000}; + TweenLite.to(myColor, 2, {hexColors:{hex:0x0000FF}, onUpdate:applyColor}); + function applyColor():void { + mc.graphics.clear(); + mc.graphics.beginFill(myColor.hex, 1); + mc.graphics.drawRect(0, 0, 100, 100); + mc.graphics.endFill(); + } + + +BYTES ADDED TO SWF: 389 (not including dependencies) + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs.plugins { + import flash.display.*; + import gs.*; + + public class HexColorsPlugin extends TweenPlugin { + public static const VERSION:Number = 1.01; + public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility + + protected var _colors:Array; + + public function HexColorsPlugin() { + super(); + this.propName = "hexColors"; + this.overwriteProps = []; + _colors = []; + } + + override public function onInitTween($target:Object, $value:*, $tween:TweenLite):Boolean { + for (var p:String in $value) { + initColor($target, p, uint($target[p]), uint($value[p])); + } + return true; + } + + public function initColor($target:Object, $propName:String, $start:uint, $end:uint):void { + if ($start != $end) { + var r:Number = $start >> 16; + var g:Number = ($start >> 8) & 0xff; + var b:Number = $start & 0xff; + _colors[_colors.length] = [$target, + $propName, + r, + ($end >> 16) - r, + g, + (($end >> 8) & 0xff) - g, + b, + ($end & 0xff) - b]; + this.overwriteProps[this.overwriteProps.length] = $propName; + } + } + + override public function killProps($lookup:Object):void { + for (var i:int = _colors.length - 1; i > -1; i--) { + if ($lookup[_colors[i][1]] != undefined) { + _colors.splice(i, 1); + } + } + super.killProps($lookup); + } + + override public function set changeFactor($n:Number):void { + var i:int, a:Array; + for (i = _colors.length - 1; i > -1; i--) { + a = _colors[i]; + a[0][a[1]] = ((a[2] + ($n * a[3])) << 16 | (a[4] + ($n * a[5])) << 8 | (a[6] + ($n * a[7]))); + } + } + + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/plugins/QuaternionsPlugin.as b/KalturaRecord/src/gs/plugins/QuaternionsPlugin.as new file mode 100644 index 0000000..f51978a --- /dev/null +++ b/KalturaRecord/src/gs/plugins/QuaternionsPlugin.as @@ -0,0 +1,135 @@ +/* +VERSION: 1.0 +DATE: 1/8/2009 +ACTIONSCRIPT VERSION: 3.0 (AS2 version is also available) +UPDATES & MORE DETAILED DOCUMENTATION AT: http://www.TweenMax.com +DESCRIPTION: + Performs SLERP interpolation between 2 Quaternions. Each Quaternion should have x, y, z, and w properties. + Simply pass in an Object containing properties that correspond to your object's quaternion properties. + For example, if your myCamera3D has an "orientation" property that's a Quaternion and you want to + tween its values to x:1, y:0.5, z:0.25, w:0.5, you could do: + + TweenLite.to(myCamera3D, 2, {quaternions:{orientation:new Quaternion(1, 0.5, 0.25, 0.5)}}); + + You can define as many quaternion properties as you want. + +USAGE: + import gs.*; + import gs.plugins.*; + TweenPlugin.activate([QuaternionsPlugin]); //only do this once in your SWF to activate the plugin + + TweenLite.to(myCamera3D, 2, {quaternions:{orientation:new Quaternion(1, 0.5, 0.25, 0.5)}}); + + +BYTES ADDED TO SWF: 700 (not including dependencies) + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs.plugins { + import gs.*; + + public class QuaternionsPlugin extends TweenPlugin { + public static const VERSION:Number = 1.0; + public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility + + protected static const _RAD2DEG:Number = 180 / Math.PI; //precalculate for speed + + protected var _target:Object; + protected var _quaternions:Array = []; + + public function QuaternionsPlugin() { + super(); + this.propName = "quaternions"; //name of the special property that the plugin should intercept/manage + this.overwriteProps = []; + } + + override public function onInitTween($target:Object, $value:*, $tween:TweenLite):Boolean { + if ($value == null) { + return false; + } + for (var p:String in $value) { + initQuaternion($target[p], $value[p], p); + } + return true; + } + + public function initQuaternion($start:Object, $end:Object, $propName:String):void { + var angle:Number, q1:Object, q2:Object, x1:Number, x2:Number, y1:Number, y2:Number, z1:Number, z2:Number, w1:Number, w2:Number, theta:Number; + q1 = $start; + q2 = $end; + x1 = q1.x; x2 = q2.x; + y1 = q1.y; y2 = q2.y; + z1 = q1.z; z2 = q2.z; + w1 = q1.w; w2 = q2.w; + angle = x1 * x2 + y1 * y2 + z1 * z2 + w1 * w2; + if (angle < 0) { + x1 *= -1; + y1 *= -1; + z1 *= -1; + w1 *= -1; + angle *= -1; + } + if ((angle + 1) < 0.000001) { + y2 = -y1; + x2 = x1; + w2 = -w1; + z2 = z1; + } + theta = Math.acos(angle); + _quaternions[_quaternions.length] = [q1, $propName, x1, x2, y1, y2, z1, z2, w1, w2, angle, theta, 1 / Math.sin(theta)]; + this.overwriteProps[this.overwriteProps.length] = $propName; + } + + override public function killProps($lookup:Object):void { + for (var i:int = _quaternions.length - 1; i > -1; i--) { + if ($lookup[_quaternions[i][1]] != undefined) { + _quaternions.splice(i, 1); + } + } + super.killProps($lookup); + } + + override public function set changeFactor($n:Number):void { + var i:int, q:Array, scale:Number, invScale:Number; + for (i = _quaternions.length - 1; i > -1; i--) { + q = _quaternions[i]; + if ((q[10] + 1) > 0.000001) { + if ((1 - q[10]) >= 0.000001) { + scale = Math.sin(q[11] * (1 - $n)) * q[12]; + invScale = Math.sin(q[11] * $n) * q[12]; + } else { + scale = 1 - $n; + invScale = $n; + } + } else { + scale = Math.sin(Math.PI * (0.5 - $n)); + invScale = Math.sin(Math.PI * $n); + } + q[0].x = scale * q[2] + invScale * q[3]; + q[0].y = scale * q[4] + invScale * q[5]; + q[0].z = scale * q[6] + invScale * q[7]; + q[0].w = scale * q[8] + invScale * q[9]; + } + /* + Array access is faster (though less readable). Here is the key: + 0 - target + 1 = propName + 2 = x1 + 3 = x2 + 4 = y1 + 5 = y2 + 6 = z1 + 7 = z2 + 8 = w1 + 9 = w2 + 10 = angle + 11 = theta + 12 = invTheta + */ + } + + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/plugins/RemoveTintPlugin.as b/KalturaRecord/src/gs/plugins/RemoveTintPlugin.as new file mode 100644 index 0000000..8112c7e --- /dev/null +++ b/KalturaRecord/src/gs/plugins/RemoveTintPlugin.as @@ -0,0 +1,39 @@ +/* +VERSION: 1.01 +DATE: 1/23/2009 +ACTIONSCRIPT VERSION: 3.0 (AS2 version is also available) +UPDATES & MORE DETAILED DOCUMENTATION AT: http://www.TweenMax.com +DESCRIPTION: + Removes the tint of a DisplayObject over time. + +USAGE: + import gs.*; + import gs.plugins.*; + TweenPlugin.activate([RemoveTintPlugin]); //only do this once in your SWF to activate the plugin (it is already activated in TweenLite and TweenMax by default) + + TweenLite.to(mc, 1, {removeTint:true}); + + +BYTES ADDED TO SWF: 61 (not including dependencies) + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs.plugins { + import flash.display.*; + import flash.geom.ColorTransform; + import gs.*; + import gs.plugins.*; + + public class RemoveTintPlugin extends TintPlugin { + public static const VERSION:Number = 1.01; + public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility + + public function RemoveTintPlugin() { + super(); + this.propName = "removeTint"; + } + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/plugins/RoundPropsPlugin.as b/KalturaRecord/src/gs/plugins/RoundPropsPlugin.as new file mode 100644 index 0000000..e3d0e29 --- /dev/null +++ b/KalturaRecord/src/gs/plugins/RoundPropsPlugin.as @@ -0,0 +1,52 @@ +/* +VERSION: 1.0 +DATE: 12/30/2008 +ACTIONSCRIPT VERSION: 3.0 (AS2 version is also available) +UPDATES & MORE DETAILED DOCUMENTATION AT: http://www.TweenMax.com +DESCRIPTION: + If you'd like the inbetween values in a tween to always get rounded to the nearest integer, use the roundProps + special property. Just pass in an Array containing the property names that you'd like rounded. For example, + if you're tweening the x, y, and alpha properties of mc and you want to round the x and y values (not alpha) + every time the tween is rendered, you'd do: + + TweenMax.to(mc, 2, {x:300, y:200, alpha:0.5, roundProps:["x","y"]}); + + roundProps requires TweenMax! TweenLite tweens will not round properties. + + +USAGE: + (this plugin is activated by default in TweenMax and cannot be activated in TweenLite) + + import gs.*; + + TweenMax.to(mc, 2, {x:300, y:200, alpha:0.5, roundProps:["x","y"]}); + + +BYTES ADDED TO SWF: 158 (not including dependencies) + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs.plugins { + import flash.display.*; + import gs.*; + + public class RoundPropsPlugin extends TweenPlugin { + public static const VERSION:Number = 1.0; + public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility + + public function RoundPropsPlugin() { + super(); + this.propName = "roundProps"; + this.overwriteProps = []; + this.round = true; + } + + public function add($object:Object, $propName:String, $start:Number, $change:Number):void { + addTween($object, $propName, $start, $start + $change, $propName); + this.overwriteProps[this.overwriteProps.length] = $propName; + } + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/plugins/ScalePlugin.as b/KalturaRecord/src/gs/plugins/ScalePlugin.as new file mode 100644 index 0000000..7c04adb --- /dev/null +++ b/KalturaRecord/src/gs/plugins/ScalePlugin.as @@ -0,0 +1,72 @@ +/* +VERSION: 1.11 +DATE: 3/20/2009 +ACTIONSCRIPT VERSION: 3.0 +UPDATES & MORE DETAILED DOCUMENTATION AT: http://www.TweenMax.com +DESCRIPTION: + ScalePlugin combines scaleX and scaleY into one "scale" property. + +USAGE: + import gs.*; + import gs.plugins.*; + TweenPlugin.activate([ScalePlugin]); //only do this once in your SWF to activate the plugin + + TweenLite.to(mc, 1, {scale:2}); //tweens horizontal and vertical scale simultaneously + + +Greensock Tweening Platform +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ +package gs.plugins { + import flash.display.*; + + import gs.*; + + public class ScalePlugin extends TweenPlugin { + public static const VERSION:Number = 1.11; + public static const API:Number = 1.0; + + protected var _target:Object; + protected var _startX:Number; + protected var _changeX:Number; + protected var _startY:Number; + protected var _changeY:Number; + + public function ScalePlugin() { + super(); + this.propName = "scale"; + this.overwriteProps = ["scaleX", "scaleY", "width", "height"]; + } + + override public function onInitTween($target:Object, $value:*, $tween:TweenLite):Boolean { + if (!$target.hasOwnProperty("scaleX")) { + return false; + } + _target = $target; + _startX = _target.scaleX; + _startY = _target.scaleY; + if (typeof($value) == "number") { + _changeX = $value - _startX; + _changeY = $value - _startY; + } else { + _changeX = _changeY = Number($value); + } + return true; + } + + override public function killProps($lookup:Object):void { + for (var i:int = this.overwriteProps.length - 1; i > -1; i--) { + if (this.overwriteProps[i] in $lookup) { //if any of the properties are found in the lookup, this whole plugin instance should be essentially deactivated. To do that, we must empty the overwriteProps Array. + this.overwriteProps = []; + return; + } + } + } + + override public function set changeFactor($n:Number):void { + _target.scaleX = _startX + ($n * _changeX); + _target.scaleY = _startY + ($n * _changeY); + } + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/plugins/SetSizePlugin.as b/KalturaRecord/src/gs/plugins/SetSizePlugin.as new file mode 100644 index 0000000..cf1d0ca --- /dev/null +++ b/KalturaRecord/src/gs/plugins/SetSizePlugin.as @@ -0,0 +1,79 @@ +/* +VERSION: 1.01 +DATE: 2/6/2009 +ACTIONSCRIPT VERSION: 3.0 (AS2 version is also available) +UPDATES & MORE DETAILED DOCUMENTATION AT: http://www.TweenMax.com +DESCRIPTION: + Some components require resizing with setSize() instead of standard tweens of width/height in + order to scale properly. The SetSizePlugin accommodates this easily. You can define the width, + height, or both. + +USAGE: + import gs.*; + import gs.plugins.*; + TweenPlugin.activate([SetSizePlugin]); //only do this once in your SWF to activate the plugin + + TweenLite.to(myComponent, 1, {setSize:{width:200, height:30}}); + + +BYTES ADDED TO SWF: 365 (not including dependencies) + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs.plugins { + import flash.display.*; + + import gs.*; + + public class SetSizePlugin extends TweenPlugin { + public static const VERSION:Number = 1.01; + public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility + + public var width:Number; + public var height:Number; + + protected var _target:Object; + protected var _setWidth:Boolean; + protected var _setHeight:Boolean; + protected var _hasSetSize:Boolean; + + public function SetSizePlugin() { + super(); + this.propName = "setSize"; + this.overwriteProps = ["setSize","width","height","scaleX","scaleY"]; + this.round = true; + } + + override public function onInitTween($target:Object, $value:*, $tween:TweenLite):Boolean { + _target = $target; + _hasSetSize = Boolean("setSize" in _target); + if ("width" in $value && _target.width != $value.width) { + addTween((_hasSetSize) ? this : _target, "width", _target.width, $value.width, "width"); + _setWidth = _hasSetSize; + } + if ("height" in $value && _target.height != $value.height) { + addTween((_hasSetSize) ? this : _target, "height", _target.height, $value.height, "height"); + _setHeight = _hasSetSize; + } + return true; + } + + override public function killProps($lookup:Object):void { + super.killProps($lookup); + if (_tweens.length == 0 || "setSize" in $lookup) { + this.overwriteProps = []; + } + } + + override public function set changeFactor($n:Number):void { + updateTweens($n); + if (_hasSetSize) { + _target.setSize((_setWidth) ? this.width : _target.width, (_setHeight) ? this.height : _target.height); + } + } + + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/plugins/ShortRotationPlugin.as b/KalturaRecord/src/gs/plugins/ShortRotationPlugin.as new file mode 100644 index 0000000..f64e6f8 --- /dev/null +++ b/KalturaRecord/src/gs/plugins/ShortRotationPlugin.as @@ -0,0 +1,66 @@ +/* +VERSION: 1.0 +DATE: 1/8/2009 +ACTIONSCRIPT VERSION: 3.0 (AS2 version is also available) +UPDATES & MORE DETAILED DOCUMENTATION AT: http://www.TweenMax.com +DESCRIPTION: + To tween any rotation property of the target object in the shortest direction, use "shortRotation" + For example, if myObject.rotation is currently 170 degrees and you want to tween it to -170 degrees, + a normal rotation tween would travel a total of 340 degrees in the counter-clockwise direction, + but if you use shortRotation, it would travel 20 degrees in the clockwise direction instead. You + can define any number of rotation properties in the shortRotation object which makes 3D tweening + easier, like TweenMax.to(mc, 2, {shortRotation:{rotationX:-170, rotationY:35, rotationZ:200}}); + +USAGE: + import gs.*; + import gs.plugins.*; + TweenPlugin.activate([ShortRotationPlugin]); //only do this once in your SWF to activate the plugin in TweenLite (it is already activated in TweenMax by default) + + TweenLite.to(mc, 1, {shortRotation:{rotation:-170}}); + + //or for a 3D tween with multiple rotation values... + TweenLite.to(mc, 1, {shortRotation:{rotationX:-170, rotationY:35, rotationZ:10}}); + + +BYTES ADDED TO SWF: 361 (not including dependencies) + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs.plugins { + import flash.display.*; + import gs.*; + + public class ShortRotationPlugin extends TweenPlugin { + public static const VERSION:Number = 1.0; + public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility + + public function ShortRotationPlugin() { + super(); + this.propName = "shortRotation"; + this.overwriteProps = []; + } + + override public function onInitTween($target:Object, $value:*, $tween:TweenLite):Boolean { + if (typeof($value) == "number") { + trace("WARNING: You appear to be using the old shortRotation syntax. Instead of passing a number, please pass an object with properties that correspond to the rotations values For example, TweenMax.to(mc, 2, {shortRotation:{rotationX:-170, rotationY:25}})"); + return false; + } + for (var p:String in $value) { + initRotation($target, p, $target[p], $value[p]); + } + return true; + } + + public function initRotation($target:Object, $propName:String, $start:Number, $end:Number):void { + var dif:Number = ($end - $start) % 360; + if (dif != dif % 180) { + dif = (dif < 0) ? dif + 360 : dif - 360; + } + addTween($target, $propName, $start, $start + dif, $propName); + this.overwriteProps[this.overwriteProps.length] = $propName; + } + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/plugins/TintPlugin.as b/KalturaRecord/src/gs/plugins/TintPlugin.as new file mode 100644 index 0000000..3a5283a --- /dev/null +++ b/KalturaRecord/src/gs/plugins/TintPlugin.as @@ -0,0 +1,84 @@ +/* +VERSION: 1.1 +DATE: 2/27/2009 +ACTIONSCRIPT VERSION: 3.0 (AS2 version is also available) +UPDATES & MORE DETAILED DOCUMENTATION AT: http://www.TweenMax.com +DESCRIPTION: + To change a DisplayObject's tint/color, set this to the hex value of the tint you'd like + to end up at (or begin at if you're using TweenMax.from()). An example hex value would be 0xFF0000. + + To remove a tint completely, use the RemoveTintPlugin (after activating it, you can just set removeTint:true) + +USAGE: + import gs.*; + import gs.plugins.*; + TweenPlugin.activate([TintPlugin]); //only do this once in your SWF to activate the plugin (it is already activated in TweenLite and TweenMax by default) + + TweenLite.to(mc, 1, {tint:0xFF0000}); + + +BYTES ADDED TO SWF: 436 (not including dependencies) + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs.plugins { + import flash.display.*; + import flash.geom.ColorTransform; + + import gs.*; + import gs.utils.tween.TweenInfo; + + public class TintPlugin extends TweenPlugin { + public static const VERSION:Number = 1.1; + public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility + protected static var _props:Array = ["redMultiplier", "greenMultiplier", "blueMultiplier", "alphaMultiplier", "redOffset", "greenOffset", "blueOffset", "alphaOffset"]; + + protected var _target:DisplayObject; + protected var _ct:ColorTransform; + protected var _ignoreAlpha:Boolean; + + public function TintPlugin() { + super(); + this.propName = "tint"; + this.overwriteProps = ["tint"]; + } + + override public function onInitTween($target:Object, $value:*, $tween:TweenLite):Boolean { + if (!($target is DisplayObject)) { + return false; + } + var end:ColorTransform = new ColorTransform(); + if ($value != null && $tween.exposedVars.removeTint != true) { + end.color = uint($value); + } + _ignoreAlpha = true; + init($target as DisplayObject, end); + return true; + } + + public function init($target:DisplayObject, $end:ColorTransform):void { + _target = $target; + _ct = _target.transform.colorTransform; + var i:int, p:String; + for (i = _props.length - 1; i > -1; i--) { + p = _props[i]; + if (_ct[p] != $end[p]) { + _tweens[_tweens.length] = new TweenInfo(_ct, p, _ct[p], $end[p] - _ct[p], "tint", false); + } + } + } + + override public function set changeFactor($n:Number):void { + updateTweens($n); + if (_ignoreAlpha) { + var ct:ColorTransform = _target.transform.colorTransform; + _ct.alphaMultiplier = ct.alphaMultiplier; + _ct.alphaOffset = ct.alphaOffset; + } + _target.transform.colorTransform = _ct; + } + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/plugins/TweenPlugin.as b/KalturaRecord/src/gs/plugins/TweenPlugin.as new file mode 100644 index 0000000..5e5de0f --- /dev/null +++ b/KalturaRecord/src/gs/plugins/TweenPlugin.as @@ -0,0 +1,213 @@ +/* +VERSION: 1.03 +DATE: 1/13/2009 +ACTIONSCRIPT VERSION: 3.0 (AS2 version is also available) +UPDATES & MORE DETAILED DOCUMENTATION AT: http://www.TweenMax.com +DESCRIPTION: + TweenPlugin is the base class for all TweenLite/TweenMax plugins. + +USAGE: + To create your own plugin, extend TweenPlugin and override whichever methods you need. Typically, + you only need to override onInitTween() and the changeFactor setter. There are a few key concepts + to keep in mind: + + - In the constructor, set this.propName to whatever special property you want your plugin to handle. + + - When a tween that uses your plugin initializes its tween values (normally when it starts), a new instance + of your plugin will be created and the onInitTween() method will be called. That's where you'll want to + store any initial values and prepare for the tween. onInitTween() should return a Boolean value that + essentially indicates whether or not the plugin initted successfully. If you return false, TweenLite/Max + will just use a normal tween for the value, ignoring the plugin for that particular tween. + + - The changeFactor setter will be updated on every frame during the course of the tween with a multiplier + that describes the amount of change based on how far along the tween is and the ease applied. It will be + zero at the beginning of the tween and 1 at the end, but inbetween it could be any value based on the + ease applied (for example, an Elastic.easeOut tween would cause the value to shoot past 1 and back again before + the end of the tween). So if the tween uses the Linear.easeNone easing equation, when it's halfway finished, + the changeFactor will be 0.5. + + - The overwriteProps is an Array that should contain the properties that your plugin should overwrite + when OverwriteManager's mode is AUTO and a tween of the same object is created. For example, the + autoAlpha plugin controls the "visible" and "alpha" properties of an object, so if another tween + is created that controls the alpha of the target object, your plugin's killProps() will be called + which should handle killing the "alpha" part of the tween. It is your responsibility to populate + (and depopulate) the overwriteProps Array. Failure to do so properly can cause odd overwriting behavior. + + - Note that there's a "round" property that indicates whether or not values in your plugin should be + rounded to the nearest integer (compatible with TweenMax only). If you use the _tweens Array, populating + it through the addTween() method, rounding will happen automatically (if necessary) in the + updateTweens() method, but if you don't use addTween() and prefer to manually calculate tween values + in your changeFactor setter, just remember to accommodate the "round" flag if it makes sense in your plugin. + + - If you need to run a block of code when the tween has finished, point the onComplete property to a + method you created inside your plugin. + + - Please use the same naming convention as the rest of the plugins, like MySpecialPropertyNamePlugin. + + - IMPORTANT: The plugin framework is brand new, so there is a chance that it will change slightly over time and + you may need to adjust your custom plugins if the framework changes. I'll try to minimize the changes, + but I'd highly recommend getting a membership to Club GreenSock to make sure you get update notifications. + See http://blog.greensock.com/club/ for details. + + +BYTES ADDED TO SWF: 560 (0.5kb) + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs.plugins { + import gs.*; + import gs.utils.tween.*; + + public class TweenPlugin { + public static const VERSION:Number = 1.03; + public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility + + /** + * Name of the special property that the plugin should intercept/handle + */ + public var propName:String; + + /** + * Array containing the names of the properties that should be overwritten in OverwriteManager's + * AUTO mode. Typically the only value in this Array is the propName, but there are cases when it may + * be different. For example, a bezier tween's propName is "bezier" but it can manage many different properties + * like x, y, etc. depending on what's passed in to the tween. + */ + public var overwriteProps:Array; + + /** + * If the values should be rounded to the nearest integer, set this to true. + */ + public var round:Boolean; + + /** + * Called when the tween is complete. + */ + public var onComplete:Function; + + protected var _tweens:Array = []; + protected var _changeFactor:Number = 0; + + + public function TweenPlugin() { + //constructor + } + + /** + * Gets called when any tween of the special property begins. Store any initial values + * and/or variables that will be used in the "changeFactor" setter when this method runs. + * + * @param $target target object of the TweenLite instance using this plugin + * @param $value The value that is passed in through the special property in the tween. + * @param $tween The TweenLite or TweenMax instance using this plugin. + * @return If the initialization failed, it returns false. Otherwise true. It may fail if, for example, the plugin requires that the target be a DisplayObject or has some other unmet criteria in which case the plugin is skipped and a normal property tween is used inside TweenLite + */ + public function onInitTween($target:Object, $value:*, $tween:TweenLite):Boolean { + addTween($target, this.propName, $target[this.propName], $value, this.propName); + return true; + } + + /** + * Offers a simple way to add tweening values to the plugin. You don't need to use this, + * but it is convenient because the tweens get updated in the updateTweens() method which also + * handles rounding. killProps() nicely integrates with most tweens added via addTween() as well, + * but if you prefer to handle this manually in your plugin, you're welcome to. + * + * @param $object target object whose property you'd like to tween. (i.e. myClip) + * @param $propName the property name that should be tweened. (i.e. "x") + * @param $start starting value + * @param $end end value (can be either numeric or a string value. If it's a string, it will be interpreted as relative to the starting value) + * @param $overwriteProp name of the property that should be associated with the tween for overwriting purposes. Normally, it's the same as $propName, but not always. For example, you may tween the "changeFactor" property of a VisiblePlugin, but the property that it's actually controling in the end is "visible", so if a new overlapping tween of the target object is created that affects its "visible" property, this allows the plugin to kill the appropriate tween(s) when killProps() is called. + */ + protected function addTween($object:Object, $propName:String, $start:Number, $end:*, $overwriteProp:String=null):void { + if ($end != null) { + var change:Number = (typeof($end) == "number") ? $end - $start : Number($end); + if (change != 0) { //don't tween values that aren't changing! It's a waste of CPU cycles + _tweens[_tweens.length] = new TweenInfo($object, $propName, $start, change, $overwriteProp || $propName, false); + } + } + } + + /** + * Updates all the tweens in the _tweens Array. + * + * @param $changeFactor Multiplier describing the amount of change that should be applied. It will be zero at the beginning of the tween and 1 at the end, but inbetween it could be any value based on the ease applied (for example, an Elastic tween would cause the value to shoot past 1 and back again before the end of the tween) + */ + protected function updateTweens($changeFactor:Number):void { + var i:int, ti:TweenInfo; + if (this.round) { + var val:Number, neg:int; + for (i = _tweens.length - 1; i > -1; i--) { + ti = _tweens[i]; + val = ti.start + (ti.change * $changeFactor); + neg = (val < 0) ? -1 : 1; + ti.target[ti.property] = ((val % 1) * neg > 0.5) ? int(val) + neg : int(val); //twice as fast as Math.round() + } + + } else { + for (i = _tweens.length - 1; i > -1; i--) { + ti = _tweens[i]; + ti.target[ti.property] = ti.start + (ti.change * $changeFactor); + } + } + } + + /** + * In most cases, your custom updating code should go here. The changeFactor value describes the amount + * of change based on how far along the tween is and the ease applied. It will be zero at the beginning + * of the tween and 1 at the end, but inbetween it could be any value based on the ease applied (for example, + * an Elastic tween would cause the value to shoot past 1 and back again before the end of the tween) + * This value gets updated on every frame during the course of the tween. + * + * @param $n Multiplier describing the amount of change that should be applied. It will be zero at the beginning of the tween and 1 at the end, but inbetween it could be any value based on the ease applied (for example, an Elastic tween would cause the value to shoot past 1 and back again before the end of the tween) + */ + public function set changeFactor($n:Number):void { + updateTweens($n); + _changeFactor = $n; + } + + public function get changeFactor():Number { + return _changeFactor; + } + + /** + * Gets called on plugins that have multiple overwritable properties by OverwriteManager when + * in AUTO mode. Basically, it instructs the plugin to overwrite certain properties. For example, + * if a bezier tween is affecting x, y, and width, and then a new tween is created while the + * bezier tween is in progress, and the new tween affects the "x" property, we need a way + * to kill just the "x" part of the bezier tween. + * + * @param $lookup An object containing properties that should be overwritten. We don't pass in an Array because looking up properties on the object is usually faster because it gives us random access. So to overwrite the "x" and "y" properties, a {x:true, y:true} object would be passed in. + */ + public function killProps($lookup:Object):void { + var i:int; + for (i = this.overwriteProps.length - 1; i > -1; i--) { + if (this.overwriteProps[i] in $lookup) { + this.overwriteProps.splice(i, 1); + } + } + for (i = _tweens.length - 1; i > -1; i--) { + if (_tweens[i].name in $lookup) { + _tweens.splice(i, 1); + } + } + } + + /** + * Handles integrating the plugin into the GreenSock tweening platform. + * + * @param $plugin An Array of Plugin classes (that all extend TweenPlugin) to be activated. For example, TweenPlugin.activate([FrameLabelPlugin, ShortRotationPlugin, TintPlugin]); + */ + public static function activate($plugins:Array):Boolean { + var i:int, instance:Object; + for (i = $plugins.length - 1; i > -1; i--) { + instance = new $plugins[i](); + TweenLite.plugins[instance.propName] = $plugins[i]; + } + return true; + } + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/plugins/VisiblePlugin.as b/KalturaRecord/src/gs/plugins/VisiblePlugin.as new file mode 100644 index 0000000..3e4bf99 --- /dev/null +++ b/KalturaRecord/src/gs/plugins/VisiblePlugin.as @@ -0,0 +1,65 @@ +/* +VERSION: 1.0 +DATE: 1/8/2009 +ACTIONSCRIPT VERSION: 3.0 (AS2 version is also available) +UPDATES & MORE DETAILED DOCUMENTATION AT: http://www.TweenMax.com +DESCRIPTION: + Toggles the visibility at the end of a tween. For example, if you want to set visible to false + at the end of the tween, do TweenLite.to(mc, 1, {x:100, visible:false}); + + The visible property is forced to true during the course of the tween. + +USAGE: + import gs.*; + import gs.plugins.*; + TweenPlugin.activate([VisiblePlugin]); //only do this once in your SWF to activate the plugin (it is already activated in TweenLite and TweenMax by default) + + TweenLite.to(mc, 1, {x:100, visible:false}); + + +BYTES ADDED TO SWF: 244 (not including dependencies) + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs.plugins { + import flash.display.*; + import gs.*; + + public class VisiblePlugin extends TweenPlugin { + public static const VERSION:Number = 1.0; + public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility + + protected var _target:Object; + protected var _tween:TweenLite; + protected var _visible:Boolean; + + public function VisiblePlugin() { + super(); + this.propName = "visible"; + this.overwriteProps = ["visible"]; + this.onComplete = onCompleteTween; + } + + override public function onInitTween($target:Object, $value:*, $tween:TweenLite):Boolean { + _target = $target; + _tween = $tween; + _visible = Boolean($value); + return true; + } + + public function onCompleteTween():void { + if (_tween.vars.runBackwards != true && _tween.ease == _tween.vars.ease) { //_tween.ease == _tween.vars.ease checks to make sure the tween wasn't reversed with a TweenGroup + _target.visible = _visible; + } + } + + override public function set changeFactor($n:Number):void { + if (_target.visible != true) { + _target.visible = true; + } + } + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/plugins/VolumePlugin.as b/KalturaRecord/src/gs/plugins/VolumePlugin.as new file mode 100644 index 0000000..fda566b --- /dev/null +++ b/KalturaRecord/src/gs/plugins/VolumePlugin.as @@ -0,0 +1,59 @@ +/* +VERSION: 1.01 +DATE: 2/17/2009 +ACTIONSCRIPT VERSION: 3.0 (AS2 version is also available) +UPDATES & MORE DETAILED DOCUMENTATION AT: http://www.TweenMax.com +DESCRIPTION: + Tweens the volume of an object with a soundTransform property (MovieClip/SoundChannel/NetStream, etc.) + +USAGE: + import gs.*; + import gs.plugins.*; + TweenPlugin.activate([VolumePlugin]); //only do this once in your SWF to activate the plugin (it is already activated in TweenLite and TweenMax by default) + + TweenLite.to(mc, 1, {volume:0}); + + +BYTES ADDED TO SWF: 275 (not including dependencies) + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs.plugins { + import flash.display.*; + import flash.media.SoundTransform; + import gs.*; + import gs.plugins.*; + + public class VolumePlugin extends TweenPlugin { + public static const VERSION:Number = 1.01; + public static const API:Number = 1.0; //If the API/Framework for plugins changes in the future, this number helps determine compatibility + + protected var _target:Object; + protected var _st:SoundTransform; + + public function VolumePlugin() { + super(); + this.propName = "volume"; + this.overwriteProps = ["volume"]; + } + + override public function onInitTween($target:Object, $value:*, $tween:TweenLite):Boolean { + if (isNaN($value) || !$target.hasOwnProperty("soundTransform")) { + return false; + } + _target = $target; + _st = _target.soundTransform; + addTween(_st, "volume", _st.volume, $value, "volume"); + return true; + } + + override public function set changeFactor($n:Number):void { + updateTweens($n); + _target.soundTransform = _st; + } + + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/utils/tween/ArrayTweenInfo.as b/KalturaRecord/src/gs/utils/tween/ArrayTweenInfo.as new file mode 100644 index 0000000..04acdca --- /dev/null +++ b/KalturaRecord/src/gs/utils/tween/ArrayTweenInfo.as @@ -0,0 +1,26 @@ +/* +VERSION: 1.0 +DATE: 1/23/2009 +ACTIONSCRIPT VERSION: 3.0 +UPDATES & MORE DETAILED DOCUMENTATION AT: http://www.TweenLite.com +DESCRIPTION: + Stores basic info about Array tweens in TweenLite/Max. + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs.utils.tween { + + public class ArrayTweenInfo { + public var index:uint; + public var start:Number; + public var change:Number; + + public function ArrayTweenInfo($index:uint, $start:Number, $change:Number) { + this.index = $index; + this.start = $start; + this.change = $change; + } + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/utils/tween/BevelFilterVars.as b/KalturaRecord/src/gs/utils/tween/BevelFilterVars.as new file mode 100644 index 0000000..5a08ee7 --- /dev/null +++ b/KalturaRecord/src/gs/utils/tween/BevelFilterVars.as @@ -0,0 +1,144 @@ +/* +VERSION: 1.01 +DATE: 1/29/2009 +ACTIONSCRIPT VERSION: 3.0 +DESCRIPTION: + This class works in conjunction with the TweenLiteVars or TweenMaxVars class to grant + strict data typing and code hinting (in most code editors) for filter tweens. See the documentation + in TweenMaxVars for more information. + +USAGE: + + Instead of TweenMax.to(my_mc, 1, {bevelFilter:{distance:5, blurX:10, blurY:10, strength:2}, onComplete:myFunction}), you could use this utility like: + + var myVars:TweenMaxVars = new TweenMaxVars(); + myVars.bevelFilter = new BevelFilterVars(5, 10, 10, 2); + myVars.onComplete = myFunction; + TweenMax.to(my_mc, 1, myVars); + + +NOTES: + - This utility is completely optional. If you prefer the shorter synatax in the regular TweenMax class, feel + free to use it. The purpose of this utility is simply to enable code hinting and to allow for strict data typing. + - You cannot define relative tween values with this utility. If you need relative values, just use the shorter (non strictly + data typed) syntax, like TweenMax.to(my_mc, 1, {bevelFilter:{blurX:"-5", blurY:"3"}}); + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + + +package gs.utils.tween { + + public class BevelFilterVars extends FilterVars { + + protected var _distance:Number; + protected var _blurX:Number; + protected var _blurY:Number; + protected var _strength:Number; + protected var _angle:Number; + protected var _highlightAlpha:Number; + protected var _highlightColor:uint; + protected var _shadowAlpha:Number; + protected var _shadowColor:uint; + protected var _quality:uint; + + public function BevelFilterVars($distance:Number=4, $blurX:Number=4, $blurY:Number=4, $strength:Number=1, $angle:Number=45, $highlightAlpha:Number=1, $highlightColor:uint=0xFFFFFF, $shadowAlpha:Number=1, $shadowColor:uint=0x000000, $quality:uint=2, $remove:Boolean=false, $index:int=-1, $addFilter:Boolean=false) { + super($remove, $index, $addFilter); + this.distance = $distance; + this.blurX = $blurX; + this.blurY = $blurY; + this.strength = $strength; + this.angle = $angle; + this.highlightAlpha = $highlightAlpha; + this.highlightColor = $highlightColor; + this.shadowAlpha = $shadowAlpha; + this.shadowColor = $shadowColor; + this.quality = $quality; + } + + public static function createFromGeneric($vars:Object):BevelFilterVars { //for parsing values that are passed in as generic Objects, like blurFilter:{blurX:5, blurY:3} (typically via the constructor) + if ($vars is BevelFilterVars) { + return $vars as BevelFilterVars; + } + return new BevelFilterVars($vars.distance || 0, + $vars.blurX || 0, + $vars.blurY || 0, + ($vars.strength == null) ? 1 : $vars.strength, + ($vars.angle == null) ? 45 : $vars.angle, + ($vars.highlightAlpha == null) ? 1 : $vars.highlightAlpha, + ($vars.highlightColor == null) ? 0xFFFFFF : $vars.highlightColor, + ($vars.shadowAlpha == null) ? 1 : $vars.shadowAlpha, + ($vars.shadowColor == null) ? 0xFFFFFF : $vars.shadowColor, + $vars.quality || 2, + $vars.remove || false, + ($vars.index == null) ? -1 : $vars.index, + $vars.addFilter || false); + } + +//---- GETTERS / SETTERS -------------------------------------------------------------------------------------------- + + public function set distance($n:Number):void { + _distance = this.exposedVars.distance = $n; + } + public function get distance():Number { + return _distance; + } + public function set blurX($n:Number):void { + _blurX = this.exposedVars.blurX = $n; + } + public function get blurX():Number { + return _blurX; + } + public function set blurY($n:Number):void { + _blurY = this.exposedVars.blurY = $n; + } + public function get blurY():Number { + return _blurY; + } + public function set strength($n:Number):void { + _strength = this.exposedVars.strength = $n; + } + public function get strength():Number { + return _strength; + } + public function set angle($n:Number):void { + _angle = this.exposedVars.angle = $n; + } + public function get angle():Number { + return _angle; + } + public function set highlightAlpha($n:Number):void { + _highlightAlpha = this.exposedVars.highlightAlpha = $n; + } + public function get highlightAlpha():Number { + return _highlightAlpha; + } + public function set highlightColor($n:uint):void { + _highlightColor = this.exposedVars.highlightColor = $n; + } + public function get highlightColor():uint { + return _highlightColor; + } + public function set shadowAlpha($n:Number):void { + _shadowAlpha = this.exposedVars.shadowAlpha = $n; + } + public function get shadowAlpha():Number { + return _shadowAlpha; + } + public function set shadowColor($n:uint):void { + _shadowColor = this.exposedVars.shadowColor = $n; + } + public function get shadowColor():uint { + return _shadowColor; + } + public function set quality($n:uint):void { + _quality = this.exposedVars.quality = $n; + } + public function get quality():uint { + return _quality; + } + + } + +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/utils/tween/BlurFilterVars.as b/KalturaRecord/src/gs/utils/tween/BlurFilterVars.as new file mode 100644 index 0000000..6221fc3 --- /dev/null +++ b/KalturaRecord/src/gs/utils/tween/BlurFilterVars.as @@ -0,0 +1,78 @@ +/* +VERSION: 1.01 +DATE: 1/29/2009 +ACTIONSCRIPT VERSION: 3.0 +DESCRIPTION: + This class works in conjunction with the TweenLiteVars or TweenMaxVars class to grant + strict data typing and code hinting (in most code editors) for filter tweens. See the documentation in + the TweenLiteVars or TweenMaxVars for more information. + +USAGE: + + Instead of TweenMax.to(my_mc, 1, {blurFilter:{blurX:10, blurY:10}, onComplete:myFunction}), you could use this utility like: + + var myVars:TweenMaxVars = new TweenMaxVars(); + myVars.blurFilter = new BlurFilterVars(10, 10); + myVars.onComplete = myFunction; + TweenMax.to(my_mc, 1, myVars); + + +NOTES: + - This utility is completely optional. If you prefer the shorter synatax in the regular TweenLite/TweenMax class, feel + free to use it. The purpose of this utility is simply to enable code hinting and to allow for strict data typing. + - You cannot define relative tween values with this utility. If you need relative values, just use the shorter (non strictly + data typed) syntax, like TweenMax.to(my_mc, 1, {blurFilter:{blurX:"-5", blurY:"3"}}); + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + + +package gs.utils.tween { + public class BlurFilterVars extends FilterVars { + protected var _blurX:Number; + protected var _blurY:Number; + protected var _quality:uint; + + public function BlurFilterVars($blurX:Number=10, $blurY:Number=10, $quality:uint=2, $remove:Boolean=false, $index:int=-1, $addFilter:Boolean=false) { + super($remove, $index, $addFilter); + this.blurX = $blurX; + this.blurY = $blurY; + this.quality = $quality; + } + + public static function createFromGeneric($vars:Object):BlurFilterVars { //for parsing values that are passed in as generic Objects, like blurFilter:{blurX:5, blurY:3} (typically via the constructor) + if ($vars is BlurFilterVars) { + return $vars as BlurFilterVars; + } + return new BlurFilterVars($vars.blurX || 0, + $vars.blurY || 0, + $vars.quality || 2, + $vars.remove || false, + ($vars.index == null) ? -1 : $vars.index, + $vars.addFilter || false); + } + +//---- GETTERS / SETTERS ------------------------------------------------------------------------------ + + public function set blurX($n:Number):void { + _blurX = this.exposedVars.blurX = $n; + } + public function get blurX():Number { + return _blurX; + } + public function set blurY($n:Number):void { + _blurY = this.exposedVars.blurY = $n; + } + public function get blurY():Number { + return _blurY; + } + public function set quality($n:uint):void { + _quality = this.exposedVars.quality = $n; + } + public function get quality():uint { + return _quality; + } + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/utils/tween/ColorMatrixFilterVars.as b/KalturaRecord/src/gs/utils/tween/ColorMatrixFilterVars.as new file mode 100644 index 0000000..d1de01c --- /dev/null +++ b/KalturaRecord/src/gs/utils/tween/ColorMatrixFilterVars.as @@ -0,0 +1,109 @@ +/* +VERSION: 1.01 +DATE: 1/29/2009 +ACTIONSCRIPT VERSION: 3.0 +DESCRIPTION: + This class works in conjunction with the TweenLiteVars or TweenMaxVars class to grant + strict data typing and code hinting (in most code editors) for filter tweens. See the documentation in + the TweenLiteVars or TweenMaxVars for more information. + +USAGE: + + Instead of TweenMax.to(my_mc, 1, {colorMatrixFilter:{colorize:0xFF0000, amount:0.5}, onComplete:myFunction}), you could use this utility like: + + var myVars:TweenMaxVars = new TweenMaxVars(); + myVars.colorMatrixFilter = new ColorMatrixFilterVars(0xFF0000, 0.5); + myVars.onComplete = myFunction; + TweenMax.to(my_mc, 1, myVars); + + +NOTES: + - This utility is completely optional. If you prefer the shorter synatax in the regular TweenLite/TweenMax class, feel + free to use it. The purpose of this utility is simply to enable code hinting and to allow for strict data typing. + - You cannot define relative tween values with this utility. If you need relative values, just use the shorter (non strictly + data typed) syntax, like TweenMax.to(my_mc, 1, {colorMatrixFilter:{contrast:0.5, relative:true}}); + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + + +package gs.utils.tween { + import gs.plugins.*; + + public class ColorMatrixFilterVars extends FilterVars { + public var matrix:Array; + + protected static var _ID_MATRIX:Array = [1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0]; + protected static var _lumR:Number = 0.212671; //Red constant - used for a few color matrix filter functions + protected static var _lumG:Number = 0.715160; //Green constant - used for a few color matrix filter functions + protected static var _lumB:Number = 0.072169; //Blue constant - used for a few color matrix filter functions + + public function ColorMatrixFilterVars($colorize:uint=0xFFFFFF, $amount:Number=1, $saturation:Number=1, $contrast:Number=1, $brightness:Number=1, $hue:Number=0, $threshold:Number=-1, $remove:Boolean=false, $index:int=-1, $addFilter:Boolean=false) { + super($remove, $index, $addFilter); + this.matrix = _ID_MATRIX.slice(); + if ($brightness != 1) { + setBrightness($brightness); + } + if ($contrast != 1) { + setContrast($contrast); + } + if ($hue != 0) { + setHue($hue); + } + if ($saturation != 1) { + setSaturation($saturation); + } + if ($threshold != -1) { + setThreshold($threshold); + } + if ($colorize != 0xFFFFFF) { + setColorize($colorize, $amount); + } + } + + public function setBrightness($n:Number):void { + this.matrix = this.exposedVars.matrix = ColorMatrixFilterPlugin.setBrightness(this.matrix, $n); + } + public function setContrast($n:Number):void { + this.matrix = this.exposedVars.matrix = ColorMatrixFilterPlugin.setContrast(this.matrix, $n); + } + public function setHue($n:Number):void { + this.matrix = this.exposedVars.matrix = ColorMatrixFilterPlugin.setHue(this.matrix, $n); + } + public function setSaturation($n:Number):void { + this.matrix = this.exposedVars.matrix = ColorMatrixFilterPlugin.setSaturation(this.matrix, $n); + } + public function setThreshold($n:Number):void { + this.matrix = this.exposedVars.matrix = ColorMatrixFilterPlugin.setThreshold(this.matrix, $n); + } + public function setColorize($color:uint, $amount:Number=1):void { + this.matrix = this.exposedVars.matrix = ColorMatrixFilterPlugin.colorize(this.matrix, $color, $amount); + } + + public static function createFromGeneric($vars:Object):ColorMatrixFilterVars { //for parsing values that are passed in as generic Objects, like blurFilter:{blurX:5, blurY:3} (typically via the constructor) + var v:ColorMatrixFilterVars; + if ($vars is ColorMatrixFilterVars) { + v = $vars as ColorMatrixFilterVars; + } else if ($vars.matrix != null) { + v = new ColorMatrixFilterVars(); + v.matrix = $vars.matrix; + } else { + v = new ColorMatrixFilterVars($vars.colorize || 0xFFFFFF, + ($vars.amount == null) ? 1 : $vars.amount, + ($vars.saturation == null) ? 1 : $vars.saturation, + ($vars.contrast == null) ? 1 : $vars.contrast, + ($vars.brightness == null) ? 1 : $vars.brightness, + $vars.hue || 0, + ($vars.threshold == null) ? -1 : $vars.threshold, + $vars.remove || false, + ($vars.index == null) ? -1 : $vars.index, + $vars.addFilter || false); + } + return v; + } + + + } + +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/utils/tween/ColorTransformVars.as b/KalturaRecord/src/gs/utils/tween/ColorTransformVars.as new file mode 100644 index 0000000..7aecbac --- /dev/null +++ b/KalturaRecord/src/gs/utils/tween/ColorTransformVars.as @@ -0,0 +1,170 @@ +/* +VERSION: 1.0 +DATE: 1/29/2009 +ACTIONSCRIPT VERSION: 3.0 +DESCRIPTION: + This class works in conjunction with the TweenLiteVars or TweenMaxVars class to grant + strict data typing and code hinting (in most code editors) for colorTransform tweens. See the documentation in + the TweenLiteVars or TweenMaxVars for more information. + +USAGE: + + Instead of TweenMax.to(my_mc, 1, {colorTransform:{exposure:2}}, onComplete:myFunction}), you could use this utility like: + + var myVars:TweenMaxVars = new TweenMaxVars(); + var ct:ColorTransformVars = new ColorTransformVars(); + ct.exposure = 2; + myVars.colorTransform = ct; + myVars.onComplete = myFunction; + TweenMax.to(my_mc, 1, myVars); + + +NOTES: + - This utility is completely optional. If you prefer the shorter synatax in the regular TweenLite/TweenMax class, feel + free to use it. The purpose of this utility is simply to enable code hinting and to allow for strict data typing. + - You cannot define relative tween values with this utility. + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + + +package gs.utils.tween { + + public class ColorTransformVars extends SubVars { + + public function ColorTransformVars($tint:Number=NaN, $tintAmount:Number=NaN, $exposure:Number=NaN, $brightness:Number=NaN, $redMultiplier:Number=NaN, $greenMultiplier:Number=NaN, $blueMultiplier:Number=NaN, $alphaMultiplier:Number=NaN, $redOffset:Number=NaN, $greenOffset:Number=NaN, $blueOffset:Number=NaN, $alphaOffset:Number=NaN) { + super(); + if (!isNaN($tint)) { + this.tint = uint($tint); + } + if (!isNaN($tintAmount)) { + this.tintAmount = $tintAmount; + } + if (!isNaN($exposure)) { + this.exposure = $exposure; + } + if (!isNaN($brightness)) { + this.brightness = $brightness; + } + if (!isNaN($redMultiplier)) { + this.redMultiplier = $redMultiplier; + } + if (!isNaN($greenMultiplier)) { + this.greenMultiplier = $greenMultiplier; + } + if (!isNaN($blueMultiplier)) { + this.blueMultiplier = $blueMultiplier; + } + if (!isNaN($alphaMultiplier)) { + this.alphaMultiplier = $alphaMultiplier; + } + if (!isNaN($redOffset)) { + this.redOffset = $redOffset; + } + if (!isNaN($greenOffset)) { + this.greenOffset = $greenOffset; + } + if (!isNaN($blueOffset)) { + this.blueOffset = $blueOffset; + } + if (!isNaN($alphaOffset)) { + this.alphaOffset = $alphaOffset; + } + } + + public static function createFromGeneric($vars:Object):ColorTransformVars { //for parsing values that are passed in as generic Objects, like blurFilter:{blurX:5, blurY:3} (typically via the constructor) + if ($vars is ColorTransformVars) { + return $vars as ColorTransformVars; + } + return new ColorTransformVars($vars.tint, + $vars.tintAmount, + $vars.exposure, + $vars.brightness, + $vars.redMultiplier, + $vars.greenMultiplier, + $vars.blueMultiplier, + $vars.alphaMultiplier, + $vars.redOffset, + $vars.greenOffset, + $vars.blueOffset, + $vars.alphaOffset); + } + +//---- GETTERS / SETTERS ------------------------------------------------------------------------------ + + public function set tint($n:Number):void { + this.exposedVars.tint = $n; + } + public function get tint():Number { + return Number(this.exposedVars.tint); + } + public function set tintAmount($n:Number):void { + this.exposedVars.tintAmount = $n; + } + public function get tintAmount():Number { + return Number(this.exposedVars.tintAmount); + } + public function set exposure($n:Number):void { + this.exposedVars.exposure = $n; + } + public function get exposure():Number { + return Number(this.exposedVars.exposure); + } + public function set brightness($n:Number):void { + this.exposedVars.brightness = $n; + } + public function get brightness():Number { + return Number(this.exposedVars.brightness); + } + public function set redMultiplier($n:Number):void { + this.exposedVars.redMultiplier = $n; + } + public function get redMultiplier():Number { + return Number(this.exposedVars.redMultiplier); + } + public function set greenMultiplier($n:Number):void { + this.exposedVars.greenMultiplier = $n; + } + public function get greenMultiplier():Number { + return Number(this.exposedVars.greenMultiplier); + } + public function set blueMultiplier($n:Number):void { + this.exposedVars.blueMultiplier = $n; + } + public function get blueMultiplier():Number { + return Number(this.exposedVars.blueMultiplier); + } + public function set alphaMultiplier($n:Number):void { + this.exposedVars.alphaMultiplier = $n; + } + public function get alphaMultiplier():Number { + return Number(this.exposedVars.alphaMultiplier); + } + public function set redOffset($n:Number):void { + this.exposedVars.redOffset = $n; + } + public function get redOffset():Number { + return Number(this.exposedVars.redOffset); + } + public function set greenOffset($n:Number):void { + this.exposedVars.greenOffset = $n; + } + public function get greenOffset():Number { + return Number(this.exposedVars.greenOffset); + } + public function set blueOffset($n:Number):void { + this.exposedVars.blueOffset = $n; + } + public function get blueOffset():Number { + return Number(this.exposedVars.blueOffset); + } + public function set alphaOffset($n:Number):void { + this.exposedVars.alphaOffset = $n; + } + public function get alphaOffset():Number { + return Number(this.exposedVars.alphaOffset); + } + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/utils/tween/DropShadowFilterVars.as b/KalturaRecord/src/gs/utils/tween/DropShadowFilterVars.as new file mode 100644 index 0000000..6c97b5b --- /dev/null +++ b/KalturaRecord/src/gs/utils/tween/DropShadowFilterVars.as @@ -0,0 +1,153 @@ +/* +VERSION: 1.01 +DATE: 1/29/2009 +ACTIONSCRIPT VERSION: 3.0 +DESCRIPTION: + This class works in conjunction with the TweenLiteVars or TweenMaxVars class to grant + strict data typing and code hinting (in most code editors) for filter tweens. See the documentation in + the TweenLiteVars or TweenMaxVars for more information. + +USAGE: + + Instead of TweenMax.to(my_mc, 1, {dropShadowFilter:{distance:5, blurX:10, blurY:10, color:0xFF0000}, onComplete:myFunction}), you could use this utility like: + + var myVars:TweenMaxVars = new TweenMaxVars(); + myVars.dropShadowFilter = new DropShadowFilterVars(5, 10, 10, 1, 45, 0xFF0000); + myVars.onComplete = myFunction; + TweenMax.to(my_mc, 1, myVars); + + +NOTES: + - This utility is completely optional. If you prefer the shorter synatax in the regular TweenLite/TweenMax class, feel + free to use it. The purpose of this utility is simply to enable code hinting and to allow for strict data typing. + - You cannot define relative tween values with this utility. If you need relative values, just use the shorter (non strictly + data typed) syntax, like TweenMax.to(my_mc, 1, {dropShadowFilter:{blurX:"-5", blurY:"3"}}); + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + + +package gs.utils.tween { + + public class DropShadowFilterVars extends FilterVars { + protected var _distance:Number; + protected var _blurX:Number; + protected var _blurY:Number; + protected var _alpha:Number; + protected var _angle:Number; + protected var _color:uint; + protected var _strength:Number; + protected var _inner:Boolean; + protected var _knockout:Boolean; + protected var _hideObject:Boolean; + protected var _quality:uint; + + public function DropShadowFilterVars($distance:Number=4, $blurX:Number=4, $blurY:Number=4, $alpha:Number=1, $angle:Number=45, $color:uint=0x000000, $strength:Number=2, $inner:Boolean=false, $knockout:Boolean=false, $hideObject:Boolean=false, $quality:uint=2, $remove:Boolean=false, $index:int=-1, $addFilter:Boolean=false) { + super($remove, $index, $addFilter); + this.distance = $distance; + this.blurX = $blurX; + this.blurY = $blurY; + this.alpha = $alpha; + this.angle = $angle; + this.color = $color; + this.strength = $strength; + this.inner = $inner; + this.knockout = $knockout; + this.hideObject = $hideObject; + this.quality = $quality; + } + + public static function createFromGeneric($vars:Object):DropShadowFilterVars { //for parsing values that are passed in as generic Objects, like blurFilter:{blurX:5, blurY:3} (typically via the constructor) + if ($vars is DropShadowFilterVars) { + return $vars as DropShadowFilterVars; + } + return new DropShadowFilterVars($vars.distance || 0, + $vars.blurX || 0, + $vars.blurY || 0, + $vars.alpha || 0, + ($vars.angle == null) ? 45 : $vars.angle, + ($vars.color == null) ? 0x000000 : $vars.color, + ($vars.strength == null) ? 2 : $vars.strength, + Boolean($vars.inner), + Boolean($vars.knockout), + Boolean($vars.hideObject), + $vars.quality || 2, + $vars.remove || false, + ($vars.index == null) ? -1 : $vars.index, + $vars.addFilter); + } + +//---- GETTERS / SETTERS -------------------------------------------------------------------------------------------- + + public function set distance($n:Number):void { + _distance = this.exposedVars.distance = $n; + } + public function get distance():Number { + return _distance; + } + public function set blurX($n:Number):void { + _blurX = this.exposedVars.blurX = $n; + } + public function get blurX():Number { + return _blurX; + } + public function set blurY($n:Number):void { + _blurY = this.exposedVars.blurY = $n; + } + public function get blurY():Number { + return _blurY; + } + public function set alpha($n:Number):void { + _alpha = this.exposedVars.alpha = $n; + } + public function get alpha():Number { + return _alpha; + } + public function set angle($n:Number):void { + _angle = this.exposedVars.angle = $n; + } + public function get angle():Number { + return _angle; + } + public function set color($n:uint):void { + _color = this.exposedVars.color = $n; + } + public function get color():uint { + return _color; + } + public function set strength($n:Number):void { + _strength = this.exposedVars.strength = $n; + } + public function get strength():Number { + return _strength; + } + public function set inner($b:Boolean):void { + _inner = this.exposedVars.inner = $b; + } + public function get inner():Boolean { + return _inner; + } + public function set knockout($b:Boolean):void { + _knockout = this.exposedVars.knockout = $b; + } + public function get knockout():Boolean { + return _knockout; + } + public function set hideObject($b:Boolean):void { + _hideObject = this.exposedVars.hideObject = $b; + } + public function get hideObject():Boolean { + return _hideObject; + } + public function set quality($n:uint):void { + _quality = this.exposedVars.quality = $n; + } + public function get quality():uint { + return _quality; + } + + + } + +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/utils/tween/FilterVars.as b/KalturaRecord/src/gs/utils/tween/FilterVars.as new file mode 100644 index 0000000..245c363 --- /dev/null +++ b/KalturaRecord/src/gs/utils/tween/FilterVars.as @@ -0,0 +1,32 @@ +/* +VERSION: 1.0 +DATE: 1/29/2009 +ACTIONSCRIPT VERSION: 3.0 +DESCRIPTION: + This class works in conjunction with the TweenLiteVars or TweenMaxVars class to grant + strict data typing and code hinting (in most code editors) for filter tweens. See the documentation in + the TweenLiteVars or TweenMaxVars for more information. + + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + + +package gs.utils.tween { + public class FilterVars extends SubVars { + public var remove:Boolean; + public var index:int; + public var addFilter:Boolean; + + public function FilterVars($remove:Boolean=false, $index:int=-1, $addFilter:Boolean=false) { + super(); + this.remove = $remove; + if ($index > -1) { + this.index = $index; + } + this.addFilter = $addFilter; + } + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/utils/tween/GlowFilterVars.as b/KalturaRecord/src/gs/utils/tween/GlowFilterVars.as new file mode 100644 index 0000000..ab9e21a --- /dev/null +++ b/KalturaRecord/src/gs/utils/tween/GlowFilterVars.as @@ -0,0 +1,126 @@ +/* +VERSION: 1.01 +DATE: 1/29/2009 +ACTIONSCRIPT VERSION: 3.0 +DESCRIPTION: + This class works in conjunction with the TweenLiteVars or TweenMaxVars class to grant + strict data typing and code hinting (in most code editors) for filter tweens. See the documentation in + the TweenLiteVars, or TweenMaxVars for more information. + +USAGE: + + Instead of TweenMax.to(my_mc, 1, {glowFilter:{blurX:10, blurY:10, color:0xFF0000}, onComplete:myFunction}), you could use this utility like: + + var myVars:TweenMaxVars = new TweenMaxVars(); + myVars.glowFilter = new GlowFilterVars(10, 10); + myVars.onComplete = myFunction; + TweenMax.to(my_mc, 1, myVars); + + +NOTES: + - This utility is completely optional. If you prefer the shorter synatax in the regular TweenLite/TweenMax class, feel + free to use it. The purpose of this utility is simply to enable code hinting and to allow for strict data typing. + - You cannot define relative tween values with this utility. If you need relative values, just use the shorter (non strictly + data typed) syntax, like TweenMax.to(my_mc, 1, {glowFilter:{blurX:"-5", blurY:"3"}}); + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + + +package gs.utils.tween { + + public class GlowFilterVars extends FilterVars { + protected var _blurX:Number; + protected var _blurY:Number; + protected var _color:uint; + protected var _alpha:Number; + protected var _strength:Number; + protected var _inner:Boolean; + protected var _knockout:Boolean; + protected var _quality:uint; + + public function GlowFilterVars($blurX:Number=10, $blurY:Number=10, $color:uint=0xFFFFFF, $alpha:Number=1, $strength:Number=2, $inner:Boolean=false, $knockout:Boolean=false, $quality:uint=2, $remove:Boolean=false, $index:int=-1, $addFilter:Boolean=false) { + super($remove, $index, $addFilter); + this.blurX = $blurX; + this.blurY = $blurY; + this.color = $color; + this.alpha = $alpha; + this.strength = $strength; + this.inner = $inner; + this.knockout = $knockout; + this.quality = $quality; + } + + public static function createFromGeneric($vars:Object):GlowFilterVars { //for parsing values that are passed in as generic Objects, like blurFilter:{blurX:5, blurY:3} (typically via the constructor) + if ($vars is GlowFilterVars) { + return $vars as GlowFilterVars; + } + return new GlowFilterVars($vars.blurX || 0, + $vars.blurY || 0, + ($vars.color == null) ? 0x000000 : $vars.color, + $vars.alpha || 0, + ($vars.strength == null) ? 2 : $vars.strength, + Boolean($vars.inner), + Boolean($vars.knockout), + $vars.quality || 2, + $vars.remove || false, + ($vars.index == null) ? -1 : $vars.index, + $vars.addFilter || false); + } + +//---- GETTERS / SETTERS ------------------------------------------------------------------------------------- + + public function set blurX($n:Number):void { + _blurX = this.exposedVars.blurX = $n; + } + public function get blurX():Number { + return _blurX; + } + public function set blurY($n:Number):void { + _blurY = this.exposedVars.blurY = $n; + } + public function get blurY():Number { + return _blurY; + } + public function set color($n:uint):void { + _color = this.exposedVars.color = $n; + } + public function get color():uint { + return _color; + } + public function set alpha($n:Number):void { + _alpha = this.exposedVars.alpha = $n; + } + public function get alpha():Number { + return _alpha; + } + public function set strength($n:Number):void { + _strength = this.exposedVars.strength = $n; + } + public function get strength():Number { + return _strength; + } + public function set inner($b:Boolean):void { + _inner = this.exposedVars.inner = $b; + } + public function get inner():Boolean { + return _inner; + } + public function set knockout($b:Boolean):void { + _knockout = this.exposedVars.knockout = $b; + } + public function get knockout():Boolean { + return _knockout; + } + public function set quality($n:uint):void { + _quality = this.exposedVars.quality = $n; + } + public function get quality():uint { + return _quality; + } + + + } + +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/utils/tween/SubVars.as b/KalturaRecord/src/gs/utils/tween/SubVars.as new file mode 100644 index 0000000..4c3004c --- /dev/null +++ b/KalturaRecord/src/gs/utils/tween/SubVars.as @@ -0,0 +1,26 @@ +/* +VERSION: 1.0 +DATE: 1/29/2009 +ACTIONSCRIPT VERSION: 3.0 +DESCRIPTION: + This class works in conjunction with the TweenLiteVars or TweenMaxVars class to grant + strict data typing and code hinting (in most code editors) for filter tweens. See the documentation in + the TweenLiteVars or TweenMaxVars for more information. + + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + + +package gs.utils.tween { + public class SubVars { + public var isTV:Boolean = true; + public var exposedVars:Object; + + public function SubVars() { + this.exposedVars = {}; + } + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/utils/tween/TransformAroundCenterVars.as b/KalturaRecord/src/gs/utils/tween/TransformAroundCenterVars.as new file mode 100644 index 0000000..0ff47b5 --- /dev/null +++ b/KalturaRecord/src/gs/utils/tween/TransformAroundCenterVars.as @@ -0,0 +1,54 @@ +/* +VERSION: 1.0 +DATE: 1/29/2009 +ACTIONSCRIPT VERSION: 3.0 +DESCRIPTION: + This class works in conjunction with the TweenLiteVars or TweenMaxVars class to grant + strict data typing and code hinting (in most code editors) for transformAroundPoint tweens. See the documentation in + the TweenLiteVars or TweenMaxVars for more information. + +USAGE: + + Instead of TweenMax.to(my_mc, 1, {transformAroundCenter:{scaleX:2, scaleY:1.5, rotation:30}}, onComplete:myFunction}), you could use this utility like: + + var myVars:TweenMaxVars = new TweenMaxVars(); + myVars.transformAroundPoint = new TransformAroundCenterVars(2, 1.5, 30); + myVars.onComplete = myFunction; + TweenMax.to(my_mc, 1, myVars); + + +NOTES: + - This utility is completely optional. If you prefer the shorter synatax in the regular TweenLite/TweenMax class, feel + free to use it. The purpose of this utility is simply to enable code hinting and to allow for strict data typing. + - You cannot define relative tween values with this utility. + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + + +package gs.utils.tween { + import flash.geom.Point; + + public class TransformAroundCenterVars extends TransformAroundPointVars { + + public function TransformAroundCenterVars($scaleX:Number=NaN, $scaleY:Number=NaN, $rotation:Number=NaN, $width:Number=NaN, $height:Number=NaN, $shortRotation:Object=null, $x:Number=NaN, $y:Number=NaN) { + super(null, $scaleX, $scaleY, $rotation, $width, $height, $shortRotation, $x, $y); + } + + public static function createFromGeneric($vars:Object):TransformAroundCenterVars { //for parsing values that are passed in as generic Objects, like blurFilter:{blurX:5, blurY:3} (typically via the constructor) + if ($vars is TransformAroundCenterVars) { + return $vars as TransformAroundCenterVars; + } + return new TransformAroundCenterVars($vars.scaleX, + $vars.scaleY, + $vars.rotation, + $vars.width, + $vars.height, + $vars.shortRotation, + $vars.x, + $vars.y); + } + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/utils/tween/TransformAroundPointVars.as b/KalturaRecord/src/gs/utils/tween/TransformAroundPointVars.as new file mode 100644 index 0000000..f512381 --- /dev/null +++ b/KalturaRecord/src/gs/utils/tween/TransformAroundPointVars.as @@ -0,0 +1,145 @@ +/* +VERSION: 1.0 +DATE: 1/29/2009 +ACTIONSCRIPT VERSION: 3.0 +DESCRIPTION: + This class works in conjunction with the TweenLiteVars or TweenMaxVars class to grant + strict data typing and code hinting (in most code editors) for transformAroundPoint tweens. See the documentation in + the TweenLiteVars or TweenMaxVars for more information. + +USAGE: + + Instead of TweenMax.to(my_mc, 1, {transformAroundPoint:{point:new Point(100, 50), scaleX:2, scaleY:1.5, rotation:30}}, onComplete:myFunction}), you could use this utility like: + + var myVars:TweenMaxVars = new TweenMaxVars(); + myVars.transformAroundPoint = new TransformAroundPointVars(new Point(100, 50), 2, 1.5, 30); + myVars.onComplete = myFunction; + TweenMax.to(my_mc, 1, myVars); + + +NOTES: + - This utility is completely optional. If you prefer the shorter synatax in the regular TweenLite/TweenMax class, feel + free to use it. The purpose of this utility is simply to enable code hinting and to allow for strict data typing. + - You cannot define relative tween values with this utility. + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + + +package gs.utils.tween { + import flash.geom.Point; + + public class TransformAroundPointVars extends SubVars { + + public function TransformAroundPointVars($point:Point=null, $scaleX:Number=NaN, $scaleY:Number=NaN, $rotation:Number=NaN, $width:Number=NaN, $height:Number=NaN, $shortRotation:Object=null, $x:Number=NaN, $y:Number=NaN) { + super(); + if ($point != null) { + this.point = $point; + } + if (!isNaN($scaleX)) { + this.scaleX = $scaleX; + } + if (!isNaN($scaleY)) { + this.scaleY = $scaleY; + } + if (!isNaN($rotation)) { + this.rotation = $rotation; + } + if (!isNaN($width)) { + this.width = $width; + } + if (!isNaN($height)) { + this.height = $height; + } + if ($shortRotation != null) { + this.shortRotation = $shortRotation; + } + if (!isNaN($x)) { + this.x = $x; + } + if (!isNaN($y)) { + this.y = $y; + } + } + + public static function createFromGeneric($vars:Object):TransformAroundPointVars { //for parsing values that are passed in as generic Objects, like blurFilter:{blurX:5, blurY:3} (typically via the constructor) + if ($vars is TransformAroundPointVars) { + return $vars as TransformAroundPointVars; + } + return new TransformAroundPointVars($vars.point, + $vars.scaleX, + $vars.scaleY, + $vars.rotation, + $vars.width, + $vars.height, + $vars.shortRotation, + $vars.x, + $vars.y); + } + +//---- GETTERS / SETTERS ------------------------------------------------------------------------------ + + public function set point($p:Point):void { + this.exposedVars.point = $p; + } + public function get point():Point { + return this.exposedVars.point; + } + public function set scaleX($n:Number):void { + this.exposedVars.scaleX = $n; + } + public function get scaleX():Number { + return Number(this.exposedVars.scaleX); + } + public function set scaleY($n:Number):void { + this.exposedVars.scaleY = $n; + } + public function get scaleY():Number { + return Number(this.exposedVars.scaleY); + } + public function set scale($n:Number):void { + this.exposedVars.scale = $n; + } + public function get scale():Number { + return Number(this.exposedVars.scale); + } + public function set rotation($n:Number):void { + this.exposedVars.rotation = $n; + } + public function get rotation():Number { + return Number(this.exposedVars.rotation); + } + public function set width($n:Number):void { + this.exposedVars.width = $n; + } + public function get width():Number { + return Number(this.exposedVars.width); + } + public function set height($n:Number):void { + this.exposedVars.height = $n; + } + public function get height():Number { + return Number(this.exposedVars.height); + } + public function set shortRotation($o:Object):void { + this.exposedVars.shortRotation = $o; + } + public function get shortRotation():Object { + return this.exposedVars.shortRotation; + } + public function set x($n:Number):void { + this.exposedVars.x = $n; + } + public function get x():Number { + return Number(this.exposedVars.x); + } + public function set y($n:Number):void { + this.exposedVars.y = $n; + } + public function get y():Number { + return Number(this.exposedVars.y); + } + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/utils/tween/TweenInfo.as b/KalturaRecord/src/gs/utils/tween/TweenInfo.as new file mode 100644 index 0000000..db0e594 --- /dev/null +++ b/KalturaRecord/src/gs/utils/tween/TweenInfo.as @@ -0,0 +1,32 @@ +/* +VERSION: 1.0 +DATE: 1/21/2009 +ACTIONSCRIPT VERSION: 3.0 +UPDATES & MORE DETAILED DOCUMENTATION AT: http://www.TweenLite.com +DESCRIPTION: + Stores basic info about individual property tweens in TweenLite/Max. + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs.utils.tween { + + public class TweenInfo { + public var target:Object; + public var property:String; + public var start:Number; + public var change:Number; + public var name:String; + public var isPlugin:Boolean; + + public function TweenInfo($target:Object, $property:String, $start:Number, $change:Number, $name:String, $isPlugin:Boolean) { + this.target = $target; + this.property = $property; + this.start = $start; + this.change = $change; + this.name = $name; + this.isPlugin = $isPlugin; + } + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/utils/tween/TweenLiteVars.as b/KalturaRecord/src/gs/utils/tween/TweenLiteVars.as new file mode 100644 index 0000000..0449866 --- /dev/null +++ b/KalturaRecord/src/gs/utils/tween/TweenLiteVars.as @@ -0,0 +1,574 @@ +/* +VERSION: 2.03 +DATE: 1/30/2009 +ACTIONSCRIPT VERSION: 3.0 +DESCRIPTION: + There are 2 primary benefits of using this utility to define your TweenLite variables: + 1) In most code editors, code hinting will be activated which helps remind you which special properties are available in TweenLite + 2) It allows you to code using strict datatyping (although it doesn't force you to). + +USAGE: + + Instead of TweenLite.to(my_mc, 1, {x:300, tint:0xFF0000, onComplete:myFunction}), you could use this utility like: + + var myVars:TweenLiteVars = new TweenLiteVars(); + myVars.addProp("x", 300); // use addProp() to add any property that doesn't already exist in the TweenLiteVars instance. + myVars.tint = 0xFF0000; + myVars.onComplete = myFunction; + TweenLite.to(my_mc, 1, myVars); + + Or if you just want to add multiple properties with one function, you can add up to 15 with the addProps() function, like: + + var myVars:TweenLiteVars = new TweenLiteVars(); + myVars.addProps("x", 300, false, "y", 100, false, "scaleX", 1.5, false, "scaleY", 1.5, false); + myVars.onComplete = myFunction; + TweenLite.to(my_mc, 1, myVars); + +NOTES: + - This class adds about 13 Kb to your published SWF (including all dependencies). + - This utility is completely optional. If you prefer the shorter synatax in the regular TweenLite class, feel + free to use it. The purpose of this utility is simply to enable code hinting and to allow for strict datatyping. + - You may add custom properties to this class if you want, but in order to expose them to TweenLite, make sure + you also add a getter and a setter that adds the property to the _exposedVars Object. + - You can reuse a single TweenLiteVars Object for multiple tweens if you want, but be aware that there are a few + properties that must be handled in a special way, and once you set them, you cannot remove them. Those properties + are: frame, visible, tint, and volume. If you are altering these values, it might be better to avoid reusing a TweenLiteVars + Object. + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs.utils.tween { + import gs.TweenLite; + + dynamic public class TweenLiteVars { + public static const version:Number = 2.03; + public const isTV:Boolean = true; // (stands for "isTweenVars") - Just gives us a way to check inside TweenLite to see if the Object is a TweenLiteVars without having to embed the class. This is helpful when handling tint, visible, and other properties that the user didn't necessarily define, but this utility class forces to be present. + /** + * The number of seconds to delay before the tween begins. + */ + public var delay:Number = 0; + /** + * An easing function (i.e. fl.motion.easing.Elastic.easeOut) The default is Regular.easeOut. + */ + public var ease:Function; + /** + * An Array of extra parameter values to feed the easing equation (beyond the standard 4). This can be useful with easing equations like Elastic that accept extra parameters like the amplitude and period. Most easing equations, however, don't require extra parameters so you won't need to pass in any easeParams. + */ + public var easeParams:Array; + /** + * A function to call when the tween begins. This can be useful when there's a delay and you want something to happen just as the tween begins. + */ + public var onStart:Function; + /** + * An Array of parameters to pass the onStart function. + */ + public var onStartParams:Array; + /** + * A function to call whenever the tweening values are updated (on every frame during the time the tween is active). + */ + public var onUpdate:Function; + /** + * An Array of parameters to pass the onUpdate function + */ + public var onUpdateParams:Array; + /** + * A function to call when the tween has completed. + */ + public var onComplete:Function; + /** + * An Array of parameters to pass the onComplete function + */ + public var onCompleteParams:Array; + /** + * NONE = 0, ALL = 1, AUTO* = 2, CONCURRENT* = 3 *Only available with the optional OverwriteManager add-on class which must be initted once for TweenLite or TweenFilterLite, like OverwriteManager.init(). TweenMax automatically inits OverwriteManager. + */ + public var overwrite:int = 2; + /** + * To prevent a tween from getting garbage collected after it completes, set persist to true. This does NOT, however, prevent teh tween from getting overwritten by other tweens of the same target. + */ + public var persist:Boolean = false; + /** + * If you're using TweenLite.from() with a delay and you want to prevent the tween from rendering until it actually begins, set this special property to true. By default, it's false which causes TweenLite.from() to render its values immediately, even before the delay has expired. + */ + public var renderOnStart:Boolean = false; + /** + * Primarily used in from() calls - forces the values to get flipped. + */ + public var runBackwards:Boolean = false; + /** + * Defines starting values for the tween (by default, the target's current values at the time the tween begins are used) + */ + public var startAt:TweenLiteVars; + + protected var _exposedVars:Object; // Gives us a way to make certain non-dynamic properties enumerable. + protected var _autoAlpha:Number; + protected var _endArray:Array; + protected var _frame:int; + protected var _frameLabel:String; + protected var _removeTint:Boolean; + protected var _tint:uint; + protected var _visible:Boolean = true; + protected var _volume:Number; + protected var _bevelFilter:BevelFilterVars; + protected var _bezier:Array; + protected var _bezierThrough:Array; + protected var _blurFilter:BlurFilterVars; + protected var _colorMatrixFilter:ColorMatrixFilterVars; + protected var _dropShadowFilter:DropShadowFilterVars; + protected var _glowFilter:GlowFilterVars; + protected var _hexColors:Object; + protected var _orientToBezier:Array; + protected var _quaternions:Object; + protected var _setSize:Object; + protected var _shortRotation:Object; + protected var _transformAroundPoint:TransformAroundPointVars; + protected var _transformAroundCenter:TransformAroundCenterVars; + protected var _colorTransform:ColorTransformVars; + + + /** + * @param $vars An Object containing properties that correspond to the properties you'd like to add to this TweenLiteVars Object. For example, TweenLiteVars({x:300, onComplete:myFunction}) + */ + public function TweenLiteVars($vars:Object = null) { + _exposedVars = {}; + if ($vars != null) { + for (var p:String in $vars) { + if (p == "blurFilter" || p == "glowFilter" || p == "colorMatrixFilter" || p == "bevelFilter" || p == "dropShadowFilter" || p == "transformAroundPoint" || p == "transformAroundCenter" || p == "colorTransform") { + //ignore SubVars - they must be handled differently later... + } else if (p != "protectedVars") { + this[p] = $vars[p]; + } + } + + if ($vars.blurFilter != null) { + this.blurFilter = BlurFilterVars.createFromGeneric($vars.blurFilter); + } + if ($vars.bevelFilter != null) { + this.bevelFilter = BevelFilterVars.createFromGeneric($vars.bevelFilter); + } + if ($vars.colorMatrixFilter != null) { + this.colorMatrixFilter = ColorMatrixFilterVars.createFromGeneric($vars.colorMatrixFilter); + } + if ($vars.dropShadowFilter != null) { + this.dropShadowFilter = DropShadowFilterVars.createFromGeneric($vars.dropShadowFilter); + } + if ($vars.glowFilter != null) { + this.glowFilter = GlowFilterVars.createFromGeneric($vars.glowFilter); + } + if ($vars.transformAroundPoint != null) { + this.transformAroundPoint = TransformAroundPointVars.createFromGeneric($vars.transformAroundPoint); + } + if ($vars.transformAroundCenter != null) { + this.transformAroundCenter = TransformAroundCenterVars.createFromGeneric($vars.transformAroundCenter); + } + if ($vars.colorTransform != null) { + this.colorTransform = ColorTransformVars.createFromGeneric($vars.colorTransform); + } + + if ($vars.protectedVars != null) { //used for clone()-ing protected vars + var pv:Object = $vars.protectedVars; + for (p in pv) { + this[p] = pv[p]; + } + } + } + if (TweenLite.version < 10.05) { + trace("TweenLiteVars error! Please update your TweenLite class or try deleting your ASO files. TweenLiteVars requires a more recent version. Download updates at http://www.TweenLite.com."); + } + } + + /** + * Adds a dynamic property for tweening and allows you to set whether the end value is relative or not + * + * @param $name Property name + * @param $value Numeric end value (or beginning value for from() calls) + * @param $relative If true, the value will be relative to the target's current value. For example, if my_mc.x is currently 300 and you do addProp("x", 200, true), the end value will be 500. + */ + public function addProp($name:String, $value:Number, $relative:Boolean = false):void { + if ($relative) { + this[$name] = String($value); + } else { + this[$name] = $value; + } + } + + /** + * Adds up to 15 dynamic properties at once (just like doing addProp() multiple times). Saves time and reduces code. + */ + public function addProps($name1:String, $value1:Number, $relative1:Boolean = false, + $name2:String = null, $value2:Number = 0, $relative2:Boolean = false, + $name3:String = null, $value3:Number = 0, $relative3:Boolean = false, + $name4:String = null, $value4:Number = 0, $relative4:Boolean = false, + $name5:String = null, $value5:Number = 0, $relative5:Boolean = false, + $name6:String = null, $value6:Number = 0, $relative6:Boolean = false, + $name7:String = null, $value7:Number = 0, $relative7:Boolean = false, + $name8:String = null, $value8:Number = 0, $relative8:Boolean = false, + $name9:String = null, $value9:Number = 0, $relative9:Boolean = false, + $name10:String = null, $value10:Number = 0, $relative10:Boolean = false, + $name11:String = null, $value11:Number = 0, $relative11:Boolean = false, + $name12:String = null, $value12:Number = 0, $relative12:Boolean = false, + $name13:String = null, $value13:Number = 0, $relative13:Boolean = false, + $name14:String = null, $value14:Number = 0, $relative14:Boolean = false, + $name15:String = null, $value15:Number = 0, $relative15:Boolean = false):void { + addProp($name1, $value1, $relative1); + if ($name2 != null) { + addProp($name2, $value2, $relative2); + } + if ($name3 != null) { + addProp($name3, $value3, $relative3); + } + if ($name4 != null) { + addProp($name4, $value4, $relative4); + } + if ($name5 != null) { + addProp($name5, $value5, $relative5); + } + if ($name6 != null) { + addProp($name6, $value6, $relative6); + } + if ($name7 != null) { + addProp($name7, $value7, $relative7); + } + if ($name8 != null) { + addProp($name8, $value8, $relative8); + } + if ($name9 != null) { + addProp($name9, $value9, $relative9); + } + if ($name10 != null) { + addProp($name10, $value10, $relative10); + } + if ($name11 != null) { + addProp($name11, $value11, $relative11); + } + if ($name12 != null) { + addProp($name12, $value12, $relative12); + } + if ($name13 != null) { + addProp($name13, $value13, $relative13); + } + if ($name14 != null) { + addProp($name14, $value14, $relative14); + } + if ($name15 != null) { + addProp($name15, $value15, $relative15); + } + } + + /** + * Clones the TweenLiteVars object. + */ + public function clone():TweenLiteVars { + var vars:Object = {protectedVars:{}}; + appendCloneVars(vars, vars.protectedVars); + return new TweenLiteVars(vars); + } + + /** + * Works with clone() to copy all the necessary properties. Split apart from clone() to take advantage of inheritence for TweenMaxVars + */ + protected function appendCloneVars($vars:Object, $protectedVars:Object):void { + var props:Array, special:Array, i:int, p:String; + props = ["delay","ease","easeParams","onStart","onStartParams","onUpdate","onUpdateParams","onComplete","onCompleteParams","overwrite","persist","renderOnStart","runBackwards","startAt"]; + for (i = props.length - 1; i > -1; i--) { + $vars[props[i]] = this[props[i]]; + } + special = ["_autoAlpha", + "_bevelFilter", + "_bezier", + "_bezierThrough", + "_blurFilter", + "_colorMatrixFilter", + "_colorTransform", + "_dropShadowFilter", + "_endArray", + "_frame", + "_frameLabel", + "_glowFilter", + "_hexColors", + "_orientToBezier", + "_quaternions", + "_removeTint", + "_setSize", + "_shortRotation", + "_tint", + "_transformAroundCenter", + "_transformAroundPoint", + "_visible", + "_volume", + "_exposedVars"]; + + for (i = special.length - 1; i > -1; i--) { + $protectedVars[special[i]] = this[special[i]]; + } + for (p in this) { + $vars[p] = this[p]; //add all the dynamic properties. + } + } + + +//---- GETTERS / SETTERS ------------------------------------------------------------------------------------------------------------- + + /** + * @return Exposes enumerable properties. + */ + public function get exposedVars():Object { + var o:Object = {}, p:String; + for (p in _exposedVars) { + o[p] = _exposedVars[p]; + } + for (p in this) { + o[p] = this[p]; //add all the dynamic properties. + } + return o; + } + + /** + * @param $n Same as changing the "alpha" property but with the additional feature of toggling the "visible" property to false when alpha is 0. + */ + public function set autoAlpha($n:Number):void { + _autoAlpha = _exposedVars.autoAlpha = $n; + } + public function get autoAlpha():Number { + return _autoAlpha; + } + + /** + * @param $a An Array containing numeric end values of the target Array. Keep in mind that the target of the tween must be an Array with at least the same length as the endArray. + */ + public function set endArray($a:Array):void { + _endArray = _exposedVars.endArray = $a; + } + public function get endArray():Array { + return _endArray; + } + + /** + * @param $b To remove the tint from a DisplayObject, set removeTint to true. + */ + public function set removeTint($b:Boolean):void { + _removeTint = _exposedVars.removeTint = $b; + } + public function get removeTint():Boolean { + return _removeTint; + } + + /** + * @param $b To set a DisplayObject's "visible" property at the end of the tween, use this special property. + */ + public function set visible($b:Boolean):void { + _visible = _exposedVars.visible = $b; + } + public function get visible():Boolean { + return _visible; + } + + /** + * @param $n Tweens a MovieClip to a particular frame. + */ + public function set frame($n:int):void { + _frame = _exposedVars.frame = $n; + } + public function get frame():int { + return _frame; + } + + /** + * @param $n Tweens a MovieClip to a particular frame. + */ + public function set frameLabel($s:String):void { + _frameLabel = _exposedVars.frameLabel = $s; + } + public function get frameLabel():String { + return _frameLabel; + } + + /** + * @param $n To change a DisplayObject's tint, set this to the hex value of the color you'd like the DisplayObject to end up at(or begin at if you're using TweenLite.from()). An example hex value would be 0xFF0000. If you'd like to remove the tint from a DisplayObject, use the removeTint special property. + */ + public function set tint($n:uint):void { + _tint = _exposedVars.tint = $n; + } + public function get tint():uint { + return _tint; + } + + /** + * @param $n To change a MovieClip's (or SoundChannel's) volume, just set this to the value you'd like the MovieClip to end up at (or begin at if you're using TweenLite.from()). + */ + public function set volume($n:Number):void { + _volume = _exposedVars.volume = $n; + } + public function get volume():Number { + return _volume; + } + + /** + * @param $f Applies a BevelFilter tween (use the BevelFilterVars utility class to define the values). + */ + public function set bevelFilter($f:BevelFilterVars):void { + _bevelFilter = _exposedVars.bevelFilter = $f; + } + public function get bevelFilter():BevelFilterVars { + return _bevelFilter; + } + + /** + * @param $a Array of Objects, one for each "control point" (see documentation on Flash's curveTo() drawing method for more about how control points work). In this example, let's say the control point would be at x/y coordinates 250,50. Just make sure your my_mc is at coordinates 0,0 and then do: TweenMax.to(my_mc, 3, {_x:500, _y:0, bezier:[{_x:250, _y:50}]}); + */ + public function set bezier($a:Array):void { + _bezier = _exposedVars.bezier = $a; + } + public function get bezier():Array { + return _bezier; + } + + /** + * @param $a Identical to bezier except that instead of passing Bezier control point values, you pass values through which the Bezier values should move. This can be more intuitive than using control points. + */ + public function set bezierThrough($a:Array):void { + _bezierThrough = _exposedVars.bezierThrough = $a; + } + public function get bezierThrough():Array { + return _bezierThrough; + } + + /** + * @param $f Applies a BlurFilter tween (use the BlurFilterVars utility class to define the values). + */ + public function set blurFilter($f:BlurFilterVars):void { + _blurFilter = _exposedVars.blurFilter = $f; + } + public function get blurFilter():BlurFilterVars { + return _blurFilter; + } + + /** + * @param $f Applies a ColorMatrixFilter tween (use the ColorMatrixFilterVars utility class to define the values). + */ + public function set colorMatrixFilter($f:ColorMatrixFilterVars):void { + _colorMatrixFilter = _exposedVars.colorMatrixFilter = $f; + } + public function get colorMatrixFilter():ColorMatrixFilterVars { + return _colorMatrixFilter; + } + + /** + * @param $ct Applies a ColorTransform tween (use the ColorTransformVars utility class to define the values). + */ + public function set colorTransform($ct:ColorTransformVars):void { + _colorTransform = _exposedVars.colorTransform = $ct; + } + public function get colorTransform():ColorTransformVars { + return _colorTransform; + } + + /** + * @param $f Applies a DropShadowFilter tween (use the DropShadowFilterVars utility class to define the values). + */ + public function set dropShadowFilter($f:DropShadowFilterVars):void { + _dropShadowFilter = _exposedVars.dropShadowFilter = $f; + } + public function get dropShadowFilter():DropShadowFilterVars { + return _dropShadowFilter; + } + + /** + * @param $f Applies a GlowFilter tween (use the GlowFilterVars utility class to define the values). + */ + public function set glowFilter($f:GlowFilterVars):void { + _glowFilter = _exposedVars.glowFilter = $f; + } + public function get glowFilter():GlowFilterVars { + return _glowFilter; + } + + /** + * @param $o Although hex colors are technically numbers, if you try to tween them conventionally, you'll notice that they don't tween smoothly. To tween them properly, the red, green, and blue components must be extracted and tweened independently. TweenMax makes it easy. To tween a property of your object that's a hex color to another hex color, use this special hexColors property of TweenMax. It must be an OBJECT with properties named the same as your object's hex color properties. For example, if your my_obj object has a "myHexColor" property that you'd like to tween to red (0xFF0000) over the course of 2 seconds, do: TweenMax.to(my_obj, 2, {hexColors:{myHexColor:0xFF0000}}); You can pass in any number of hexColor properties. + */ + public function set hexColors($o:Object):void { + _hexColors = _exposedVars.hexColors = $o; + } + public function get hexColors():Object { + return _hexColors; + } + + /** + * @param $a A common effect that designers/developers want is for a MovieClip/Sprite to orient itself in the direction of a Bezier path (alter its rotation). orientToBezier makes it easy. In order to alter a rotation property accurately, TweenMax needs 4 pieces of information: + * + * 1. Position property 1 (typically "x") + * 2. Position property 2 (typically "y") + * 3. Rotational property (typically "rotation") + * 4. Number of degrees to add (optional - makes it easy to orient your MovieClip/Sprite properly) + * + * The orientToBezier property should be an Array containing one Array for each set of these values. For maximum flexibility, you can pass in any number of Arrays inside the container Array, one for each rotational property. This can be convenient when working in 3D because you can rotate on multiple axis. If you're doing a standard 2D x/y tween on a bezier, you can simply pass in a boolean value of true and TweenMax will use a typical setup, [["x", "y", "rotation", 0]]. Hint: Don't forget the container Array (notice the double outer brackets) + */ + public function set orientToBezier($a:*):void { + if ($a is Array) { + _orientToBezier = _exposedVars.orientToBezier = $a; + } else if ($a == true) { + _orientToBezier = _exposedVars.orientToBezier = [["x", "y", "rotation", 0]]; + } else { + _orientToBezier = null; + delete _exposedVars.orientToBezier; + } + } + public function get orientToBezier():* { + return _orientToBezier; + } + + /** + * @param $q An object with properties that correspond to the quaternion properties of the target object. For example, if your my3DObject has "orientation" and "childOrientation" properties that contain quaternions, and you'd like to tween them both, you'd do: {orientation:myTargetQuaternion1, childOrientation:myTargetQuaternion2}. Quaternions must have the following properties: x, y, z, and w. + */ + public function set quaternions($q:Object):void { + _quaternions = _exposedVars.quaternions = $q; + } + public function get quaternions():Object { + return _quaternions; + } + + /** + * @param $o An object containing a "width" and/or "height" property which will be tweened over time and applied using setSize() on every frame during the course of the tween. + */ + public function set setSize($o:Object):void { + _setSize = _exposedVars.setSize = $o; + } + public function get setSize():Object { + return _setSize; + } + + /** + * @param $o To tween any rotation property (even multiple properties) of the target object in the shortest direction, use shortRotation. For example, if myObject.rotation is currently 170 degrees and you want to tween it to -170 degrees, a normal rotation tween would travel a total of 340 degrees in the counter-clockwise direction, but if you use shortRotation, it would travel 20 degrees in the clockwise direction instead. Pass in an object in with properties that correspond to the rotation values of the target, like {rotation:-170} or {rotationX:-170, rotationY:50} + */ + public function set shortRotation($o:Object):void { + _shortRotation = _exposedVars.shortRotation = $o; + } + public function get shortRotation():Object { + return _shortRotation; + } + + /** + * @param $tp Applies a transformAroundCenter tween (use the TransformAroundCenterVars utility class to define the values). + */ + public function set transformAroundCenter($tp:TransformAroundCenterVars):void { + _transformAroundCenter = _exposedVars.transformAroundCenter = $tp; + } + public function get transformAroundCenter():TransformAroundCenterVars { + return _transformAroundCenter; + } + + /** + * @param $tp Applies a transformAroundPoint tween (use the TransformAroundPointVars utility class to define the values). + */ + public function set transformAroundPoint($tp:TransformAroundPointVars):void { + _transformAroundPoint = _exposedVars.transformAroundPoint = $tp; + } + public function get transformAroundPoint():TransformAroundPointVars { + return _transformAroundPoint; + } + + + } +} \ No newline at end of file diff --git a/KalturaRecord/src/gs/utils/tween/TweenMaxVars.as b/KalturaRecord/src/gs/utils/tween/TweenMaxVars.as new file mode 100644 index 0000000..831479c --- /dev/null +++ b/KalturaRecord/src/gs/utils/tween/TweenMaxVars.as @@ -0,0 +1,113 @@ +/* +VERSION: 2.01 +DATE: 1/19/2009 +ACTIONSCRIPT VERSION: 3.0 +DESCRIPTION: + There are 2 primary benefits of using this utility to define your TweenMax variables: + 1) In most code editors, code hinting will be activated which helps remind you which special properties are available in TweenMax + 2) It allows you to code using strict datatyping (although it doesn't force you to). + +USAGE: + + Instead of TweenMax.to(my_mc, 1, {x:300, tint:0xFF0000, onComplete:myFunction}), you could use this utility like: + + var myVars:TweenMaxVars = new TweenMaxVars(); + myVars.addProp("x", 300); // use addProp() to add any property that doesn't already exist in the TweenMaxVars instance. + myVars.tint = 0xFF0000; + myVars.onComplete = myFunction; + TweenMax.to(my_mc, 1, myVars); + + Or if you just want to add multiple properties with one function, you can add up to 15 with the addProps() function, like: + + var myVars:TweenMaxVars = new TweenMaxVars(); + myVars.addProps("x", 300, false, "y", 100, false, "scaleX", 1.5, false, "scaleY", 1.5, false); + myVars.onComplete = myFunction; + TweenMax.to(my_mc, 1, myVars); + +NOTES: + - This class adds about 14 Kb to your published SWF. + - This utility is completely optional. If you prefer the shorter synatax in the regular TweenMax class, feel + free to use it. The purpose of this utility is simply to enable code hinting and to allow for strict datatyping. + - You may add custom properties to this class if you want, but in order to expose them to TweenMax, make sure + you also add a getter and a setter that adds the property to the _exposedVars Object. + - You can reuse a single TweenMaxVars Object for multiple tweens if you want, but be aware that there are a few + properties that must be handled in a special way, and once you set them, you cannot remove them. Those properties + are: frame, visible, tint, and volume. If you are altering these values, it might be better to avoid reusing a TweenMaxVars + Object. + +AUTHOR: Jack Doyle, jack@greensock.com +Copyright 2009, GreenSock. All rights reserved. This work is subject to the terms in http://www.greensock.com/terms_of_use.html or for corporate Club GreenSock members, the software agreement that was issued with the corporate membership. +*/ + +package gs.utils.tween { + import gs.utils.tween.TweenLiteVars; + + dynamic public class TweenMaxVars extends TweenLiteVars { + public static const version:Number = 2.01; + /** + * A function to which the TweenMax instance should dispatch a TweenEvent when it begins. This is the same as doing myTweenMaxInstance.addEventListener(TweenEvent.START, myFunction); + */ + public var onStartListener:Function; + /** + * A function to which the TweenMax instance should dispatch a TweenEvent every time it updates values. This is the same as doing myTweenMaxInstance.addEventListener(TweenEvent.UPDATE, myFunction); + */ + public var onUpdateListener:Function; + /** + * A function to which the TweenMax instance should dispatch a TweenEvent when it completes. This is the same as doing myTweenMaxInstance.addEventListener(TweenEvent.COMPLETE, myFunction); + */ + public var onCompleteListener:Function; + /** + * To make the tween reverse when it completes (like a yoyo) any number of times, set this to the number of cycles you'd like the tween to yoyo. A value of zero causes the tween to yoyo endlessly. + */ + public var yoyo:Number; + /** + * To make the tween repeat when it completes any number of times, set this to the number of cycles you'd like the tween to loop. A value of zero causes the tween to loop endlessly. + */ + public var loop:Number; + + protected var _roundProps:Array; + + /** + * @param $vars An Object containing properties that correspond to the properties you'd like to add to this TweenMaxVars Object. For example, TweenMaxVars({blurFilter:{blurX:10, blurY:20}, onComplete:myFunction}) + */ + public function TweenMaxVars($vars:Object = null) { + super($vars); + } + + /** + * Clones the TweenMaxVars object. + */ + override public function clone():TweenLiteVars { + var vars:Object = {protectedVars:{}}; + appendCloneVars(vars, vars.protectedVars); + return new TweenMaxVars(vars); + } + + /** + * Works with clone() to copy all the necessary properties. Split apart from clone() to take advantage of inheritence + */ + override protected function appendCloneVars($vars:Object, $protectedVars:Object):void { + super.appendCloneVars($vars, $protectedVars); + var props:Array = ["onStartListener","onUpdateListener","onCompleteListener","onCompleteAllListener","yoyo","loop"]; + for (var i:int = props.length - 1; i > -1; i--) { + $vars[props[i]] = this[props[i]]; + } + $protectedVars._roundProps = _roundProps; + } + + +//---- GETTERS / SETTERS --------------------------------------------------------------------------------------------- + + /** + * @param $a An Array of the names of properties that should be rounded to the nearest integer when tweening + */ + public function set roundProps($a:Array):void { + _roundProps = _exposedVars.roundProps = $a; + } + public function get roundProps():Array { + return _roundProps; + } + + + } +} \ No newline at end of file