Commit 978dbef4 authored by Anssi Piirainen's avatar Anssi Piirainen
Browse files

Merge pull request #33 from flowplayer/danielr-httpstreaming

#27 regression caused by #550, only stop the player for live streams. ca...
parents 32f8637d 5c81e901
Version history:
3.2.15
------
- #15 fixes for #627, handle the display init on startup.
- #615 dispatch begin if in paused mode too early.
- #629 if start has been dispatched already prevent dispatching many begin events.
- #20 for the free player swap the logo with the stage video mask to display underneath not on top.
- #42 pass in stream clips through and close the stream before returning to the parent clip.
- #52 when replaying flag start has dispatched on the current clip.
- #44 fixes for #627 check if the stagevideo dimensions and positioning has changed to update the stage video mask with.
unbinding and binding stage video events caused issues with instream playlists therefore has to be kept binded.
unbinded stage video events during seeking to prevent the mask repositioning.
- #53 update url filter to accomodate for pretty urls with semi colons.
- #50 if we have metadata already set it is being updated during seeks and switching, dispatch metadata change events instead.
3.2.14
------
- #614 when the clip ends if the next clip in the provider has a different provider close the provider stream.
- #627 only detach / attach the display on start events which causes issues in buffering events after a seek in stagevideo.
- #627 re-enable stagevideo state change listeners if stagevideo is available or detach the fullscreen events on first call.
- #9 when replaying from stopping, connection does not receive callbacks anymore.
- #15 fixes for #627, handle the display init on startup.
- #615 dispatch begin if in paused mode too early.
- #629 if start has been dispatched already prevent dispatching many begin events.
- #20 for the free player swap the logo with the stage video mask to display underneath not on top.
3.2.13
------
......
......@@ -47,6 +47,7 @@ package org.flowplayer.controller {
}
public function onMetaData(infoObject:Object):void {
log.info("onMetaData, current clip " + _clip);
log.debug("onMetaData, data for clip " + _clip + ":");
......@@ -77,7 +78,7 @@ package org.flowplayer.controller {
}
log.debug("metaData : ", metaData);
_clip.metaData = metaData;
if (metaData.cuePoints && _clip.cuepoints.length == 0) {
log.debug("clip has embedded cuepoints");
......@@ -86,7 +87,15 @@ package org.flowplayer.controller {
_previousUrl = _clip.url;
_clip.dispatch(ClipEventType.METADATA);
//#50 if we have metadata already set it is being updated during seeks and switching, dispatch metadata change events instead.
if (_clip.metaData) {
_clip.metaData = metaData;
_clip.dispatch(ClipEventType.METADATA_CHANGED);
} else {
_clip.metaData = metaData;
_clip.dispatch(ClipEventType.METADATA);
}
log.info("metaData parsed and injected to the clip");
}
......
......@@ -138,13 +138,23 @@ package org.flowplayer.controller {
return clip.provider == (_model ? _model.name : (clip.parent ? 'httpInstream' : 'http'));
});
//#50 dispatch metadata events on updates also
clip.onMetaDataChange(onMetaData, function(clip:Clip):Boolean {
return clip.provider == (_model ? _model.name : (clip.parent ? 'httpInstream' : 'http'));
});
//#614 when the clip ends if the next clip in the provider has a different provider close the provider stream.
clip.onFinish(closeStream, function():Boolean {
clip.onFinish(closeStream, function(clip:Clip):Boolean {
//#42 pass instream clips through and close the stream
if (clip.isInStream) return true;
return _player.playlist.hasNext() && _player.playlist.nextClip.provider !== _model.name;
});
clip.startDispatched = false;
//#50 clear metadata when replaying in a playlist
clip.metaData = false;
log.debug("previously started clip " + _startedClip);
if (attempts == 3 && _startedClip && _startedClip == clip && _connection && _netStream) {
log.info("playing previous clip again, reusing existing connection and resuming");
......@@ -164,17 +174,19 @@ package org.flowplayer.controller {
*/
private function closeStream(event:ClipEvent):void
{
netStream.close();
if (netStream) netStream.close();
_startedClip = null;
event.target.unbind(closeStream);
}
private function replay(clip:Clip):void {
try {
clip.dispatchEvent(new ClipEvent(ClipEventType.BEGIN, _pauseAfterStart));
//#52 when replaying flag start has dispatched on the current clip.
clip.startDispatched = true;
seek(new ClipEvent(ClipEventType.SEEK, 0), 0);
netStream.resume();
_started = true;
clip.dispatchEvent(new ClipEvent(ClipEventType.BEGIN, _pauseAfterStart));
clip.dispatchEvent(new ClipEvent(ClipEventType.START));
} catch (e:Error) {
if (e.errorID == 2154) {
......@@ -533,15 +545,20 @@ package org.flowplayer.controller {
protected function doSwitchStream(event:ClipEvent, netStream:NetStream, clip:Clip, netStreamPlayOptions:Object = null):void {
//fix for #279, switch and pause if the current clip is currently in a paused state
//#404 implement netstreamplayoptions for http streams, resets the stream or start loading a new stream.
if (netStreamPlayOptions) {
pauseAfterStart = paused;
import flash.net.NetStreamPlayOptions;
if (netStreamPlayOptions is NetStreamPlayOptions) {
log.debug("doSwitchStream() calling play2()");
//#461 when we have a clip base url set, we need the complete clip url sent to play2 for http streams.
netStreamPlayOptions.streamName = clip.completeUrl;
netStream.play2(netStreamPlayOptions as NetStreamPlayOptions);
}
//implement switch support for flash9 players that do not support dynamic switching
if (CONFIG::FLASH_10_1) {
if (netStreamPlayOptions) {
pauseAfterStart = paused;
import flash.net.NetStreamPlayOptions;
if (netStreamPlayOptions is NetStreamPlayOptions) {
log.debug("doSwitchStream() calling play2()");
//#461 when we have a clip base url set, we need the complete clip url sent to play2 for http streams.
netStreamPlayOptions.streamName = clip.completeUrl;
netStream.play2(netStreamPlayOptions as NetStreamPlayOptions);
}
} else {
load(event, clip, this._paused);
}
} else {
load(event, clip, this._paused);
}
......@@ -802,6 +819,8 @@ package org.flowplayer.controller {
private function onConnectionSuccess(connection:NetConnection):void {
_connection = connection;
//reset start dispatching if reconnecting
clip.startDispatched = false;
//#430 adding event listeners for netconnection
connection.addEventListener(NetStatusEvent.NET_STATUS, _onNetStatus);
_createNetStream();
......
......@@ -54,7 +54,7 @@ package org.flowplayer.model {
if (eventType == ClipEventType.CUEPOINT) {
return Cuepoint(info).callbackId;
}
if ([ClipEventType.START, ClipEventType.UPDATE, ClipEventType.METADATA, ClipEventType.RESUME, ClipEventType.BEGIN].indexOf(eventType) >= 0) {
if ([ClipEventType.START, ClipEventType.UPDATE, ClipEventType.METADATA, ClipEventType.METADATA_CHANGED, ClipEventType.RESUME, ClipEventType.BEGIN].indexOf(eventType) >= 0) {
return target;
}
return super.externalEventArgument2;
......
......@@ -61,6 +61,10 @@ package org.flowplayer.model {
setListener(ClipEventType.METADATA, listener, clipFilter, false, addToFront);
}
public function onMetaDataChange(listener:Function, clipFilter:Function = null, addToFront:Boolean = false):void {
setListener(ClipEventType.METADATA_CHANGED, listener, clipFilter, false, addToFront);
}
public function onBeforeBegin(listener:Function, clipFilter:Function = null, addToFront:Boolean = false):void {
setListener(ClipEventType.BEGIN, listener, clipFilter, true, addToFront);
}
......
......@@ -26,6 +26,7 @@ import org.flowplayer.flow_internal;
public static const CONNECT:ClipEventType = new ClipEventType("onConnect");
public static const BEGIN:ClipEventType = new ClipEventType("onBegin");
public static const METADATA:ClipEventType = new ClipEventType("onMetaData");
public static const METADATA_CHANGED:ClipEventType = new ClipEventType("onMetaDataChange");
public static const START:ClipEventType = new ClipEventType("onStart");
public static const PAUSE:ClipEventType = new ClipEventType("onPause");
public static const RESUME:ClipEventType = new ClipEventType("onResume");
......
......@@ -36,7 +36,8 @@ package org.flowplayer.util {
}
public static function isValid(URL:String):Boolean {
var regex:RegExp = /^http(s)?:\/\/((\d+\.\d+\.\d+\.\d+)|(([\w-]+\.)+([a-z,A-Z][\w-]*)))(:[1-9][0-9]*)?(\/([\w-.\/:%+@&=]+[\w- .\/?:%+@&=]*)?)?(#(.*))?$/i;
//#53 update url filter to accomodate for pretty urls with semi colons.
var regex:RegExp = /^http(s)?:\/\/((\d+\.\d+\.\d+\.\d+)|(([\w-]+\.)+([a-z,A-Z][\w-]*)))(:[1-9][0-9]*)?(\/(?:%+@&=)|([\w-.\/:;%+@&=]+[\w-.\/?:;%+@&=]*)?)?(#(.*))?$/i;
return regex.test(URL);
}
......
......@@ -16,8 +16,6 @@
* along with Flowplayer. If not, see <http://www.gnu.org/licenses/>.
*/
package org.flowplayer.view {
import flash.external.ExternalInterface;
import org.flowplayer.config.Config;
import org.flowplayer.config.ConfigParser;
import org.flowplayer.config.ExternalInterfaceHelper;
......@@ -25,12 +23,12 @@ package org.flowplayer.view {
import org.flowplayer.controller.PlayListController;
import org.flowplayer.controller.ResourceLoader;
import org.flowplayer.controller.ResourceLoaderImpl;
import org.flowplayer.flow_internal;
import org.flowplayer.flow_internal;
import org.flowplayer.model.Callable;
import org.flowplayer.model.Clip;
import org.flowplayer.model.ClipEvent;
import org.flowplayer.model.ClipEventType;
import org.flowplayer.model.DisplayPluginModel;
import org.flowplayer.model.ClipEventType;
import org.flowplayer.model.DisplayPluginModel;
import org.flowplayer.model.DisplayProperties;
import org.flowplayer.model.DisplayPropertiesImpl;
import org.flowplayer.model.ErrorCode;
......@@ -101,7 +99,6 @@ import org.flowplayer.model.DisplayPluginModel;
private var _clickCount:int;
private var _clickTimer:Timer = new Timer(200, 1);
private var _clickEvent:MouseEvent;
private var _screenMask:Sprite;
[Frame(factoryClass="org.flowplayer.view.Preloader")]
......@@ -740,14 +737,19 @@ import org.flowplayer.model.DisplayPluginModel;
//#508 disabling the stagevideo screen mask, canvas is visible without it.
CONFIG::FLASH_10_1 {
_flowplayer.playlist.onStageVideoStateChange(onStageVideoStateChange);
_flowplayer.playlist.onStageVideoStateChange(onStageVideoStateChange);
//#44 fixes for #627, now bind and unbind stagevideo events during seeking to prevent the mask repositioning.
_flowplayer.playlist.onBeforeSeek(function(event:ClipEvent):void {
_flowplayer.playlist.unbind(onStageVideoStateChange);
});
//#627 re-enable stagevideo state change listeners if stagevideo is available or detach the fullscreen events on first call.
_flowplayer.onFullscreen(onStageVideoFullscreen);
_flowplayer.onFullscreenExit(onStageVideoFullscreen);
_flowplayer.playlist.onSeek(function(event:ClipEvent):void {
_flowplayer.playlist.onStageVideoStateChange(onStageVideoStateChange);
});
}
}
private function onMouseOut(event:MouseEvent):void {
_flowplayer.dispatchEvent(PlayerEvent.mouseOut());
}
......@@ -757,56 +759,54 @@ import org.flowplayer.model.DisplayPluginModel;
}
//#508 disabling the stagevideo screen mask, canvas is visible without it.
CONFIG::FLASH_10_1 {
CONFIG::FLASH_10_1 {
private function onStageVideoStateChange(event:ClipEvent):void {
var stageVideo:StageVideo = event.info as StageVideo;
log.info("stage video state changed " + stageVideo);
log.debug("stage video state changed " + stageVideo);
if ( stageVideo ) {
if (stageVideo) {
//#44 fixes for #627 check if the stagevideo dimensions and positioning has changed to update the stage video mask with.
//unbinding and binding stage video events caused issues with instream playlists therefore has to be kept binded.
if (_screenMask.width !== stageVideo.viewPort.width) {
_screenMask.width = stageVideo.viewPort.width;
}
if (_screenMask.height !== stageVideo.viewPort.height) {
_screenMask.height = stageVideo.viewPort.height;
}
_screenMask.width = stageVideo.viewPort.width;
_screenMask.height = stageVideo.viewPort.height;
_screenMask.x = stageVideo.viewPort.x;
_screenMask.y = stageVideo.viewPort.y;
if (_screenMask.x !== stageVideo.viewPort.x) _screenMask.x = stageVideo.viewPort.x;
if (_screenMask.y !== stageVideo.viewPort.y) _screenMask.y = stageVideo.viewPort.y;
log.debug("mask dimensions " + _screenMask.width + " x " + _screenMask.height);
log.debug("mask pos " + _screenMask.x + ", " + _screenMask.y);
if ( ! contains(_screenMask) ) {
//#508 stage video mask was being added to the top layer and hiding all children.
addChildAt(_screenMask, 0);
if (!contains(_screenMask)) {
//#508 stage video mask was being added to the top layer and hiding all children.
//_canvasLogo.visible = false;
//#20 for the free player swap the logo with the stage video mask to display underneath not on top.
CONFIG::freeVersion {
swapChildren(_screenMask, _canvasLogo);
addChildAt(_screenMask, 0);
swapChildren(_screenMask, _copyrightNotice);
swapChildren(_screenMask, _canvasLogo);
}
CONFIG::commercialVersion {
addChildAt(_screenMask, 1);
}
//addChildAt(_screenMask, _canvasLogo ? 1 : 0);
log.debug("adding mask");
}
//#627 unbind the stagevideo state change events after the screen mask is setup.
_flowplayer.playlist.unbind(onStageVideoStateChange);
} else {
if ( contains(_screenMask) ) {
if (contains(_screenMask)) {
log.debug("removing mask")
removeChild(_screenMask);
_flowplayer.playlist.unbind(onStageVideoStateChange);
}
}
}
/**
* #627 re-enable stagevideo state change listeners if stagevideo is available or detach the fullscreen events on first call.
* @param event
*/
private function onStageVideoFullscreen(event:PlayerEvent):void
{
//#627 if stage video is not configured or available unbind the fullscreen events on first try.
if (!_flowplayer.playlist.current.useStageVideo) {
_flowplayer.unbind(onStageVideoFullscreen);
}
_flowplayer.playlist.onStageVideoStateChange(onStageVideoStateChange);
}
}
private function createPanel():void {
......
......@@ -170,14 +170,17 @@ package org.flowplayer.view {
return;
var p:Point = localToGlobal(new Point(0, 0));
var r:Rectangle = _visible ? new Rectangle(p.x, p.y, width, height) : new Rectangle(0, 0, 0, 0);
_stageVideo.viewPort = r;
_clip.dispatch(ClipEventType.STAGE_VIDEO_STATE_CHANGE, stageVideo);
}
override public function set width(value:Number):void {
super.width = value;
_updateStageVideo();
}
override public function set height(value:Number):void {
......
......@@ -146,6 +146,24 @@ package org.flowplayer.ui.dock {
_autoHide.stop(leaveVisible);
}
//#60 add helper methods to hide / show the dock when autohide is enabled or not.
[External]
public function show():void {
if (_config.autoHide.enabled)
startAutoHide()
else
_player.animationEngine.fadeIn(this);
}
[External]
public function hide():void {
if (_config.autoHide.enabled)
stopAutoHide(false);
else
_player.animationEngine.fadeOut(this);
}
public function cancelAnimation():void {
_autoHide.cancelAnimation();
}
......
......@@ -342,12 +342,12 @@ package org.flowplayer.ui.tooltips {
private function setOffset():void {
switch( this._align ){
case "left":
case "right":
this._offSet = - _defaultWidth + ( _buffer * 6 ) + this._hookSize;
this._hookOffSet = this._defaultWidth - ( _buffer * 6 ) - this._hookSize;
this._hookOffSet = this._defaultWidth - ( _buffer * 6 ) - this._hookSize;
break;
case "right":
case "left":
this._offSet = 0 - ( _buffer * 6 ) - this._hookSize;
this._hookOffSet = _buffer * 6 + this._hookSize;
break;
......
......@@ -13,7 +13,7 @@
<property name="lib-dir" value="lib" />
<property name="flex-libs-path" value="${flexlibsdir}" />
<property name="flowplayer-js-version-info" value="3.1.4" />
<property name="src-flowplayer" value="../core" />
<property name="src-flowplayer" value="../../core" />
<property name="plugin-swc" value="${basename}.swc" />
<property name="plugin-swc-versioned" value="${basename}-${version}.swc" />
......
Version history:
3.2.9
-----
- Refactored to changes in the google analytics library for Bridge mode support. Debug view support is removed but with the option of a build build. Reinstating the trackingObj config
to configure the bridge mode.
TODO: May require V5 async support. _gat._getTracker is deprecated use _gat._createTracker instead.
3.2.8
-----
- Bridge mode now removed from code also
......
<project name="Google Analytics plugin for Flowplayer" default="deploy">
<property file="build.generated.properties"/>
<property file="${user.home}/plugin.properties" />
<property file="build.properties"/>
<property file="../../lib/devkit/plugin-build.properties" />
<import file="../../lib/devkit/plugin-build.xml"/>
<property name="flowplayer_lib" value="../core/build/flowplayer.swc" />
<property name="library-path" value="lib-swc" />
<property name="compiler-defines" value="-define+=LOG::P,'true'"/>
<property name="shortname" value="analytics" />
<property name="basename" value="flowplayer.${shortname}-debug" />
<property name="releasedir" value="flowplayer.analytics" />
<property name="plugin-binary" value="${basename}.swf" />
<property name="plugin-binary-versioned" value="${basename}-${version}.swf" />
<property name="plugin-main-class" value="org/flowplayer/analytics/GoogleTracker.as" />
</project>
\ No newline at end of file
<project name="Google Analytics plugin for Flowplayer" default="deploy">
<property file="build.generated.properties"/>
<property file="${user.home}/plugin.properties" />
<property file="build.properties"/>
<property file="../../lib/devkit/plugin-build.properties" />
<import file="../../lib/devkit/plugin-build.xml"/>
<property name="flowplayer_lib" value="../core/build/flowplayer.swc" />
<property name="library-path" value="lib" />
<property name="library-path" value="lib-swc" />
<property name="compiler-defines" value="-define+=LOG::P,'false'"/>
<property name="shortname" value="analytics" />
<property name="basename" value="flowplayer.${shortname}" />
......@@ -14,4 +16,8 @@
<property name="plugin-binary-versioned" value="${basename}-${version}.swf" />
<property name="plugin-main-class" value="org/flowplayer/analytics/GoogleTracker.as" />
<target name="build-debug">
<ant antfile="build-debug.xml" target="deploy" inheritall="false" />
</target>
</project>
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment