Jump to content
Search Community

m1gu3l

Members
  • Posts

    9
  • Joined

  • Last visited

Contact Methods

Profile Information

  • Location
    Lodz

m1gu3l's Achievements

0

Reputation

  1. 1. true, you can, but only if sound is already preloading when you check. 2. the goal was to get something like this (---animation---###sounds###---animation---###sound###---animation---) in an easy way - if i don't pause the timeline and wait for sound to preload and just play it, i could loose sync on low-bandwidth connection. i totally agree it's not a good code, but it works for this one purpose. about pausing, i think i could hack around by overriding paused getter and setter and using some additional variable to define whether it was paused by user or by itself. 3. because sometimes Sound is neither preloaded nor preloading, i pass predefined length (2s ) to the tween, just in case, and when it loads i alter it to correct length - and to sync with next tweens in timeline i need to alter their startTime params.
  2. Looks like problem with anti-aliasing, try different settings.
  3. TweenPlugin handling sound would be problematic, and I believe it can't be done for not-preloaded Sounds within current greensock architecture, because: * still preloading Sound object has no length or incorrect length * you can pause tween and wait for Sound object to load, but you can't pause a tween's parent (Timeline) * you can change tween duration, but you can't shiftChildren of tween's parent (Timeline) Correct me, if I am wrong, because I would love to do this
  4. Working (99%) version. package pl.m1gu3l.gs { import com.greensock.easing.Linear; import com.greensock.TimelineLite; import com.greensock.TweenLite; import flash.events.Event; import flash.media.Sound; import flash.media.SoundChannel; import flash.utils.Dictionary; /** * ... * @author michal.przybys */ public class SoundTimeline extends TimelineLite { private var currentSound:Sound; private var currentChannel:SoundChannel; private var pausedPosition:Number; private var dict:Dictionary; /** * @param vars optionally pass in special properties like useFrames, onComplete, onCompleteParams, onUpdate, onUpdateParams, * onStart, onStartParams, tweens, align, stagger, delay, reversed, and/or autoRemoveChildren. */ public function SoundTimeline(vars:Object = null) { if (vars == null) vars = { paused: true } dict = new Dictionary(true); super(vars); } /** * Converts Sound to TweenLite and appends it to timeline * * @param sound Sound * @param onComplete Function to be fired after Sound completes * @param onCompleteParams an Array of parameters for onComplete function */ public function appendSound(sound:Sound, onComplete:Function = null, onCompleteParams:Array = null):void { this.append(soundToTween(sound, onComplete, onCompleteParams)); } /** * Converts Sound to TweenLite and prepends it to timeline * * @param sound Sound * @param onComplete Function to be fired after Sound completes * @param onCompleteParams an Array of parameters for onComplete function */ public function prependSound(sound:Sound, onComplete:Function = null, onCompleteParams:Array = null):void { this.prepend(soundToTween(sound, onComplete, onCompleteParams)); } /** * Converts an Array of Sound objects to TweenLite and appends it to timeline * * @param sound an Array of Sound objects * @param onComplete Function to be fired after last of passed Sound objects completes * @param onCompleteParams an Array of parameters for onComplete function */ public function appendMultipleSounds(sounds:Array, onComplete:Function = null, onCompleteParams:Array = null):void { for (var i:int = 0; i < sounds.length ; i++) { var tween:TweenLite = (i == sounds.length - 1) ? soundToTween(sounds[i], onComplete, onCompleteParams) : soundToTween(sounds[i]); this.append(tween); } } /** * Converts an Array of Sound objects to TweenLite and prepends it to timeline * * @param sound an Array of Sound objects * @param onComplete Function to be fired after last of passed Sound objects completes * @param onCompleteParams an Array of parameters for onComplete function */ public function prependMultipleSounds(sounds:Array, onComplete:Function = null, onCompleteParams:Array = null):void { for (var i:int = sounds.length - 1; i >= 0; i--) { var tween:TweenLite = (i == 0) ? soundToTween(sounds[i], onComplete, onCompleteParams) : soundToTween(sounds[i]); this.prepend(tween); } } /** * Converts Function to TweenLite and appends it to timeline * * @param f Function to be fired * @param params an Array of parameters for passed function */ public function appendFunction(f:Function, params:Array = null):void { this.append(TweenLite.delayedCall(0.1, f, params)); } /** * Converts Function to TweenLite and prepends it to timeline * * @param f Function to be fired * @param params an Array of parameters for passed function */ public function prependFunction(f:Function, params:Array = null):void { this.prepend(TweenLite.delayedCall(0.1, f, params)); } override public function stop():void { super.stop(); if (currentChannel != null) currentChannel.stop(); currentChannel = null; currentSound = null; } override public function pause():void { super.pause(); if (currentChannel != null) { pausedPosition = currentChannel.position; currentChannel.stop(); } } override public function resume():void { super.resume(); if (currentSound != null) currentChannel = currentSound.play(pausedPosition); } /** * Converts Sound to TweenLite and returns it * * @param sound Sound * @param onComplete Function to be fired after Sound completes * @param onCompleteParams an Array of parameters for onComplete function * @return com.greensock.TweenLite */ public function soundToTween(sound:Sound, onComplete:Function = null, onCompleteParams:Array = null):TweenLite { if (sound == null) throw new Error('sound passed is null'); var time:Number; if (!isPreloaded(sound)) { time = 2; sound.addEventListener(Event.COMPLETE, setDurationAfterLoaded); } else { time = sound.length * 0.001; } var tl:TweenLite = new TweenLite(this, time, { ease: Linear.easeNone, onStart: function() { currentSound = sound; if (!isPreloaded(sound)) { pauseForLoading(sound); } else { currentChannel = currentSound.play(); } }, onComplete: function() { currentSound = null; currentChannel = null; (onComplete != null) ? onComplete.call(this, onCompleteParams) : null; } } ); dict[sound] = tl; return tl; } private function pauseForLoading(sound:Sound):void { sound.addEventListener(Event.COMPLETE, resumeAfterLoaded); super.pause(); } private function resumeAfterLoaded(e:Event):void { e.target.removeEventListener(Event.COMPLETE, resumeAfterLoaded); super.resume(); currentChannel = currentSound.play(); } private function setDurationAfterLoaded(e:Event):void { e.target.removeEventListener(Event.COMPLETE, setDurationAfterLoaded); var time:Number = e.target.length * 0.001; var tween:TweenLite = dict[e.target]; tween.duration = time; shiftChildren(time, true, tween.startTime + 0.1); } private function isPreloaded(sound:Sound):Boolean { return sound.bytesTotal != 0 ? (sound.bytesLoaded >= sound.bytesTotal) : false; } } } the remaining not working 1% throws null pointer error @ get totalDuration() of TimelineLite, when preceding tween is really short override public function get totalDuration():Number { if (this.cacheIsDirty) { var max:Number = 0, end:Number, tween:TweenCore = (this.gc) ? _endCaps[0] : _firstChild, prevStart:Number = -Infinity, next:TweenCore; while (tween) { next = tween.nextNode; //record it here in case the tween changes position in the sequence... if (tween.cachedStartTime < prevStart) { //in case one of the tweens shifted out of order, it needs to be re-inserted into the correct position in the sequence this.insert(tween, tween.cachedStartTime - tween.delay); // ----- prevNode is null -------------------------------------------------- prevStart = tween.prevNode.cachedStartTime; // after changing to the following, it works 100% // prevStart = tween.prevNode ? tween.prevNode.cachedStartTime : 0; } else { prevStart = tween.cachedStartTime; } if (tween.cachedStartTime < 0) { //children aren't allowed to have negative startTimes, so adjust here if one is found. max -= tween.cachedStartTime; this.shiftChildren(-tween.cachedStartTime, false, -9999999999); } end = tween.cachedStartTime + (tween.totalDuration / tween.cachedTimeScale); if (end > max) { max = end; } tween = next; } this.cachedDuration = this.cachedTotalDuration = max; this.cacheIsDirty = false; } return this.cachedTotalDuration; }
  5. Oj, I am completely aware it's gonna have drawbacks, I don't think anyone would want timeScale to alter Sound (however it is possible, via SampleDataEvent), it should also be possible to cover other problems, but it wasn't the goal. I am looking for just easy, rapid way of content generation Good idea with making this as a plugin, thanks.
  6. The main problem is: * if sound is not preloaded, it has no duration * if it has no duration, i need to set some predefined duration for tween * when sound preloads, i need to alter preset duration of tween to duration of sound * it doesn't work
  7. It has a TimelineLite as a superclass so it basically has all the stuff implemented by Jack, you can nest and nest something inside it and so on... it can be reversed, but it won't play sounds while so - but feel free to alter the class and implement this. I attached a sample Flash CS5/Flash Develop project
  8. If I want to build a timeline with f.e. text-to-speech sounds based on user actions, it would be nice if I could skip the preloading part and let the timeline handle it. To achieve this I thought I could just change the duration of child tween as the Sound object finishes preloading (let's say for now all Sound objects are still preloading during the creation of timeline, but are already preloaded when timeline starts) - and it doesn't work so well :/ package pl.m1gu3l.gs { import com.greensock.TimelineLite; import com.greensock.TweenLite; import flash.display.Sprite; import flash.events.Event; import flash.media.Sound; import flash.media.SoundChannel; import flash.utils.Dictionary; /** * ... * @author michal.przybys */ public class SoundTimeline extends TimelineLite { private var currentSound:Sound; private var currentChannel:SoundChannel; private var pausedPosition:Number; private var dict:Dictionary; /** * @param vars optionally pass in special properties like useFrames, onComplete, onCompleteParams, onUpdate, onUpdateParams, * onStart, onStartParams, tweens, align, stagger, delay, reversed, and/or autoRemoveChildren. */ public function SoundTimeline(vars:Object = null) { if (vars == null) vars = { paused: true } dict = new Dictionary(true); super(vars); } /** * Converts Sound to TweenLite and appends it to timeline * * @param sound Sound * @param onComplete Function to be fired after Sound completes * @param onCompleteParams an Array of parameters for onComplete function */ public function appendSound(sound:Sound, onComplete:Function = null, onCompleteParams:Array = null):void { this.append(soundToTween(sound, onComplete, onCompleteParams)); } /** * Converts Sound to TweenLite and prepends it to timeline * * @param sound Sound * @param onComplete Function to be fired after Sound completes * @param onCompleteParams an Array of parameters for onComplete function */ public function prependSound(sound:Sound, onComplete:Function = null, onCompleteParams:Array = null):void { this.prepend(soundToTween(sound, onComplete, onCompleteParams)); } /** * Converts an Array of Sound objects to TweenLite and appends it to timeline * * @param sound an Array of Sound objects * @param onComplete Function to be fired after last of passed Sound objects completes * @param onCompleteParams an Array of parameters for onComplete function */ public function appendMultipleSounds(sounds:Array, onComplete:Function = null, onCompleteParams:Array = null):void { for (var i:int = 0; i < sounds.length ; i++) { var tween:TweenLite = (i == sounds.length - 1) ? soundToTween(sounds[i], onComplete, onCompleteParams) : soundToTween(sounds[i]); this.append(tween); } } /** * Converts an Array of Sound objects to TweenLite and prepends it to timeline * * @param sound an Array of Sound objects * @param onComplete Function to be fired after last of passed Sound objects completes * @param onCompleteParams an Array of parameters for onComplete function */ public function prependMultipleSounds(sounds:Array, onComplete:Function = null, onCompleteParams:Array = null):void { for (var i:int = sounds.length - 1; i >= 0; i--) { var tween:TweenLite = (i == 0) ? soundToTween(sounds[i], onComplete, onCompleteParams) : soundToTween(sounds[i]); this.prepend(tween); } } /** * Converts Function to TweenLite and appends it to timeline * * @param f Function to be fired * @param params an Array of parameters for passed function */ public function appendFunction(f:Function, params:Array = null):void { this.append(TweenLite.delayedCall(0.1, f, params)); } /** * Converts Function to TweenLite and prepends it to timeline * * @param f Function to be fired * @param params an Array of parameters for passed function */ public function prependFunction(f:Function, params:Array = null):void { this.prepend(TweenLite.delayedCall(0.1, f, params)); } override public function stop():void { super.stop(); if (currentChannel != null) currentChannel.stop(); currentChannel = null; currentSound = null; } override public function pause():void { super.pause(); if (currentChannel != null) { pausedPosition = currentChannel.position; currentChannel.stop(); } } override public function resume():void { super.resume(); if (currentSound != null) currentChannel = currentSound.play(pausedPosition); } /** * Converts Sound to TweenLite and returns it * * @param sound Sound * @param onComplete Function to be fired after Sound completes * @param onCompleteParams an Array of parameters for onComplete function * @return com.greensock.TweenLite */ public function soundToTween(sound:Sound, onComplete:Function = null, onCompleteParams:Array = null):TweenLite { if (sound == null) throw new Error('sound passed is null'); var time:uint; if (!isPreloaded(sound)) { time = 1; sound.addEventListener(Event.COMPLETE, setDurationAfterLoaded); } else { time = sound.length / 1000; } var tl:TweenLite = new TweenLite(this, time, { onStart: function() { currentSound = sound; currentChannel = currentSound.play(); trace('start'); }, onComplete: function() { trace('complete'); currentSound = null; currentChannel = null; (onComplete != null) ? onComplete.call(this, onCompleteParams) : null; } } ); dict[sound] = tl; return tl; } private function setDurationAfterLoaded(e:Event):void { trace('setduration', dict[e.target].duration, totalDuration); dict[e.target].duration = e.target.length / 1000; totalDuration += e.target.length / 1000 - 1; trace('to', dict[e.target].duration, totalDuration); } private function isPreloaded(sound:Sound):Boolean { return sound.bytesTotal != 0 ? (sound.bytesLoaded >= sound.bytesTotal) : false; } } } any suggestions?
  9. Hi everybody. I've written a small class extending TimelineLite, so that I could add Sound objects to tween queue. package pl.m1gu3l.gs { import com.greensock.TimelineLite; import com.greensock.TweenLite; import flash.media.Sound; import flash.media.SoundChannel; /** * ... * @author michal.przybys */ public class SoundTimeline extends TimelineLite { private var currentSound:Sound; private var currentChannel:SoundChannel; private var pausedPosition:Number; /** * @param vars optionally pass in special properties like useFrames, onComplete, onCompleteParams, onUpdate, onUpdateParams, * onStart, onStartParams, tweens, align, stagger, delay, reversed, and/or autoRemoveChildren. */ public function SoundTimeline(vars:Object = null) { if (vars == null) vars = { paused: true } super(vars); } /** * Converts preloaded Sound to TweenLite and appends it to timeline * * @param preloadedSound preloaded Sound * @param onComplete Function to be fired after Sound completes * @param onCompleteParams an Array of parameters for onComplete function */ public function appendSound(preloadedSound:Sound, onComplete:Function = null, onCompleteParams:Array = null):void { this.append(soundToTween(preloadedSound, onComplete, onCompleteParams)); } /** * Converts preloaded Sound to TweenLite and prepends it to timeline * * @param preloadedSound preloaded Sound * @param onComplete Function to be fired after Sound completes * @param onCompleteParams an Array of parameters for onComplete function */ public function prependSound(preloadedSound:Sound, onComplete:Function = null, onCompleteParams:Array = null):void { this.prepend(soundToTween(preloadedSound, onComplete, onCompleteParams)); } /** * Converts an Array of preloaded Sound objects to TweenLite and appends it to timeline * * @param preloadedSound an Array of preloaded Sound objects * @param onComplete Function to be fired after last of passed Sound objects completes * @param onCompleteParams an Array of parameters for onComplete function */ public function appendMultipleSounds(preloadedSounds:Array, onComplete:Function = null, onCompleteParams:Array = null):void { for (var i:int = 0; i < preloadedSounds.length ; i++) { var tween:TweenLite = (i == preloadedSounds.length - 1) ? soundToTween(preloadedSounds[i], onComplete, onCompleteParams) : soundToTween(preloadedSounds[i]); this.append(tween); } } /** * Converts an Array of preloaded Sound objects to TweenLite and prepends it to timeline * * @param preloadedSound an Array of preloaded Sound objects * @param onComplete Function to be fired after last of passed Sound objects completes * @param onCompleteParams an Array of parameters for onComplete function */ public function prependMultipleSounds(preloadedSounds:Array, onComplete:Function = null, onCompleteParams:Array = null):void { for (var i:int = preloadedSounds.length - 1; i >= 0; i--) { var tween:TweenLite = (i == 0) ? soundToTween(preloadedSounds[i], onComplete, onCompleteParams) : soundToTween(preloadedSounds[i]); this.prepend(tween); } } /** * Converts Function to TweenLite and appends it to timeline * * @param f Function to be fired * @param params an Array of parameters for passed function */ public function appendFunction(f:Function, params:Array = null):void { this.append(TweenLite.delayedCall(0, f, params)); } /** * Converts Function to TweenLite and prepends it to timeline * * @param f Function to be fired * @param params an Array of parameters for passed function */ public function prependFunction(f:Function, params:Array = null):void { this.prepend(TweenLite.delayedCall(0, f, params)); } override public function stop():void { super.stop(); if (currentChannel != null) currentChannel.stop(); currentChannel = null; currentSound = null; } override public function pause():void { super.pause(); if (currentChannel != null) { pausedPosition = currentChannel.position; currentChannel.stop(); } } override public function resume():void { super.resume(); if (currentSound != null) currentChannel = currentSound.play(pausedPosition); } /** * Converts preloaded Sound to TweenLite and returns it * * @param preloadedSound preloaded Sound * @param onComplete Function to be fired after Sound completes * @param onCompleteParams an Array of parameters for onComplete function * @return com.greensock.TweenLite */ public function soundToTween(preloadedSound:Sound, onComplete:Function = null, onCompleteParams:Array = null):TweenLite { if (preloadedSound == null) throw new Error('sound passed is null'); if (preloadedSound.bytesLoaded < preloadedSound.bytesTotal || preloadedSound.bytesTotal == 0) throw new Error('sound not preloaded'); return new TweenLite(this, preloadedSound.length / 1000, { onStart: function() { currentSound = preloadedSound; currentChannel = preloadedSound.play(); }, onComplete: function() { currentSound = null; currentChannel = null; (onComplete != null) ? onComplete.call(this, onCompleteParams) : null; } } ); } } } As you can see it requires all passed Sound objects to be already prealoaded, which is fine if you know what you wanna play.
×
×
  • Create New...