Flex Videodisplay und direkte Zeitmarken
Ich habe momentan das Problem, dass ich bei der Videodisplay-Komponente nicht direkt an eine bestimmte Stelle springen kann. Dieses Problem lässt sich momentan leider nicht umgehen, da man an der Methode seek() nichts anpassen kann. Aus diesem Grund habe ich begonnen einen kleinen workaround zu erstellen. Dazu auch nochmal vielen Dank für den Tipp beim Flex UG event, zu den keyframes innerhalb des Videos, die bei H.264 nochmal anders gesetzt werden.
Der workaround sieht so aus, dass das Video erst dann wieder eingeblendet wird, wenn die Zeitmarke erreicht ist. Das Videodisplay springt automatisch, durch die seek Methode einen kleinen Schritt zurück und das mache ich mir zu nutze. Beim setzten der playheadtime und anschließendem play(), wird ein bitmap erzeugt und über das Video gelegt. Ebenso wird die Lautstärke auf 0 gesetzt. Wird die Zeitmarke wieder erreicht, wird das bitmap entfernt und die Lautstärke zurückgesetzt. Bis zu diesem Punkt wird auch die update-Methode unterbrochen.
/**
* @author Christian Müller
* @date 16.01.2010
* @url http://www.christian-mueller-design.de
*/
package de.cmd.videodisplay {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.PixelSnapping;
import flash.display.Sprite;
import mx.controls.VideoDisplay;
import mx.events.VideoEvent;
public class AccurateVideoDisplay extends VideoDisplay {
private var _targetPositionSet : Boolean; // if new position set from outside
private var _targetPlayHeadTime : Number; // playheadtime video has to reach
private var _targetVolume : Number; // video volume on new playheadtime
private var _overlayImage : Sprite; // sprite containing screenshot of video while loading
public function AccurateVideoDisplay() {
super();
_targetPositionSet = false;
playheadUpdateInterval = 50;
addEventListener( VideoEvent.PLAYHEAD_UPDATE, onPlayHeadUpdateTrigger ); // overwrite event
}
override public function get playheadTime():Number {
return super.playheadTime;
}
override public function set playheadTime( value:Number ):void {
// set target values
_targetPositionSet = true;
_targetPlayHeadTime = value;
_targetVolume = this.volume;
// set new playheadtime
super.playheadTime = value;
// create and add screenshot
displayWaitingImage();
}
override public function play():void {
super.play();
}
// called when playheadtime changes
private function onPlayHeadUpdateTrigger( event:VideoEvent ):void {
// playhead update event will not be dispatched until targetplayheadtime reached
// outside nothing will happen until targettime
if ( _targetPositionSet ) {
event.stopImmediatePropagation();
}
// check if target playheadtime reached
if ( playheadTime >= _targetPlayHeadTime ) { // success
// screenshot existing
if ( _overlayImage != null ) {
var index : Number = getChildIndex( _overlayImage );
if ( index > -1 ) {
// remove screenshot and recreate old state
removeChildAt( index );
_overlayImage = null;
volume = _targetVolume;
_targetPositionSet = false;
}
}
}
}
// create screenshot of current videoposition
private function displayWaitingImage():void {
// set remove sound and add screenshot
volume = 0;
var screenshot : BitmapData = new BitmapData( this.width, this.height );
screenshot.draw( this );
var overlayImageBmp : Bitmap = new Bitmap( screenshot, PixelSnapping.AUTO, true );
_overlayImage = new Sprite();
_overlayImage.addChild( overlayImageBmp );
addChild( _overlayImage );
}
}
}
Der Entwicklungsstand ist ehr als Alpha zu bezeichnen, da nur Standardoperationen verwendet werden. Allerdings dient sie schonmal als gute Basis.
Ich würde mich auch über andere Ratschläge oder Weiterentwicklungen freuen.
