Commit 186000e7 authored by Anssi Piirainen's avatar Anssi Piirainen
Browse files

Prepare for 3.2.17 release: Updated README files.

parent 39430416
......@@ -5,6 +5,7 @@ Version history:
- #75 set the child display list different when a gradient is set.
- The clip property 'bufferLength' now accepts decimal values, for example bufferLength: 0.2
- #121 only load plugins and external config from the same domain as the player swf from loaded from
- Made it possible to tab out of the player and into the HTML page using the keyboard alone.
3.2.16
------
......
/*
* Copyright (c) 2008 Michael A. Jordan
* Copyright (c) 2009 Adobe Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the copyright holders nor the names of its 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 HOLDER 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.
*/
/*
This code is based on Adobe's SWFFocus class.
The original SWFFocus class is designed to resolve the accessibility issue in browsers other than Internet Explorer
when users can't access player controls by keyboard alone. This accessibility issue can be viewed in 2 parts:
1. User can't access player's controls, tabbing skips over the player.
2. Once user has a focus on player's controls, he can tab through player's controls, but he is 'trapped' inside the player and can't
shift focus back to the html page elements.
Task #1 is not working in several browsers including Chrome and Opera on Windows. This issue is resolved by javascript code and does not require changes
in the AS.
Task #2 is resolved by this class and is using the same idea as Adobe's SWFFocus class uses - it injects javascript code into html page embedding the player.
The code monitors objects receiving the focus and once the user has made a full circle (the first object received a focus again) it injects the javascript
that shifts focus to the designated "next" html element on the page embedding the player.
Code modified by: Gita Ligure
GLigure@Books24x7.com
November 12th, 2013
*/
package org.flowplayer.view
{
import flash.display.DisplayObject;
import flash.display.InteractiveObject;
import flash.display.Stage;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.FocusEvent;
import flash.events.KeyboardEvent;
import flash.external.ExternalInterface;
import flash.system.Capabilities;
import flash.ui.Keyboard;
import flash.utils.setTimeout;
import org.flowplayer.util.Log;
public class Focus extends EventDispatcher
{
private var log:Log = new Log(this);
private static var _availability:Boolean = ExternalInterface.available;
private static var _dispatcher:EventDispatcher = new EventDispatcher();
private static var _instance:Focus = new Focus( SingletonLock );
private static var _initialized:Boolean = false;
private var _stage:Stage;
private var _firstRoundTabbing:Boolean = true;
private var _ignoreNextEvents:Boolean = false;
private var _firstTabbedObject:InteractiveObject;
private var _idNext:String;
/**
*
* Constructor
*/
public function Focus( lock:Class )
{
if ( lock != SingletonLock )
{
throw new Error( "Invalid Singleton access. Use Focus.init." );
}
}
/**
*
* Initiates swffocus object, and sets callbacks
*/
public static function init(stageRef:Stage):void
{
var swffocus:Focus = _instance;
if (stageRef && swffocus._stage != stageRef && !_initialized)
{
swffocus._stage = stageRef;
_initialized = swffocus._initialize();
}
}
/**
* @private
* Set event handles and inject JavaScript code
*/
private function _initialize():Boolean
{
log.info("Initializing Focus ");
if (_availability && Capabilities.playerType.toLowerCase() == "plugin" && !Focus._initialized)
{
ExternalInterface.addCallback("setNextFocusId", _instance.setNextFocusId);
_stage.addEventListener(FocusEvent.FOCUS_IN, stage_focusInHandler, false, 0, true);
_stage.addEventListener(FocusEvent.FOCUS_OUT, stage_focusOutHandler, false, 0, true);
}
return true;
}
/**
* @private compares with a stored first object tabbed into
* and if they match, calls javascript to set focus to a next
* html element on the page
*/
private function stage_focusOutHandler(e:FocusEvent):void
{
if (_ignoreNextEvents != true)
{
if (!_firstRoundTabbing)
{
if (_firstTabbedObject && e.relatedObject)
{
if (_firstTabbedObject.name == e.relatedObject.name) // make sure objects not null
{
log.info("IT'S A MATCH First object Stored: " + _firstTabbedObject.name + " related object " + e.relatedObject.name);
// reset for next round
_firstTabbedObject = null;
_firstRoundTabbing = true;
_ignoreNextEvents = true;
if (_idNext)
{
log.info("Should set focus on element " + _idNext);
ExternalInterface.call("function(){var elem = document.getElementById('" +_idNext + "'); if (elem) elem.focus();}");
}
}
}
}
else
{
_firstRoundTabbing = false;
}
}
else
_ignoreNextEvents = false;
}
/**
* @private stores the first target focus;
*/
private function stage_focusInHandler(e:FocusEvent):void
{
if (_ignoreNextEvents != true)
{
if (_firstRoundTabbing)
{
log.info("Will store " + e.target + " as a first Tabbed object ");
if (e.currentTarget) _firstTabbedObject = InteractiveObject(e.target);
}
}
}
/**
*
* Callback function for JavaScript, used to set IDs of next and previous
* elements in the HTML tab order.
*
*/
public function setNextFocusId(idNext:String):void
{
if (idNext)
_idNext = idNext;
}
}
}
/**
* This is a private class declared outside of the package
* that is only accessible to classes inside of the Focus.as
* file. Because of that, no outside code is able to get a
* reference to this class to pass to the constructor, which
* enables us to prevent outside instantiation.
*/
class SingletonLock
{
} // end class
......@@ -16,6 +16,8 @@
* 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;
......@@ -23,12 +25,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;
......@@ -46,8 +48,7 @@ package org.flowplayer.view {
import org.flowplayer.model.ProviderModel;
import org.flowplayer.model.State;
import org.flowplayer.util.Arrange;
import org.flowplayer.util.DomainUtil;
import org.flowplayer.util.Log;
import org.flowplayer.util.Log;
import org.flowplayer.util.TextUtil;
import org.flowplayer.util.URLUtil;
import org.flowplayer.view.Panel;
......@@ -100,6 +101,7 @@ import org.flowplayer.util.Log;
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")]
......@@ -214,6 +216,7 @@ import org.flowplayer.util.Log;
log.debug("no loadable plugins, calling initPhase4");
initPhase4();
}
Focus.init(stage);
}
private function initPhase4(event:Event = null):void {
......@@ -622,15 +625,7 @@ import org.flowplayer.util.Log;
callAndHandleError(initPhase1, PlayerError.INIT_FAILED);
} else {
var configUrl:String = configObj.hasOwnProperty("url") ? String(configObj["url"]) : configStr;
if (! DomainUtil.allowCodeLoading(configUrl)) {
log.error("Cannot load config from " + configUrl + ", only player's domain is accepted");
throw new Error("Cannot load config from " + configUrl + ", only player's domain is accepted");
return;
}
ConfigParser.loadConfig(configUrl, BuiltInConfig.config, function(config:Config):void {
ConfigParser.loadConfig(configObj.hasOwnProperty("url") ? String(configObj["url"]) : configStr, BuiltInConfig.config, function(config:Config):void {
_config = config;
callAndHandleError(initPhase1, PlayerError.INIT_FAILED);
}, new ResourceLoaderImpl(null, this), loaderInfo.url, VersionInfo.controlsVersion, VersionInfo.audioVersion);
......@@ -746,19 +741,14 @@ import org.flowplayer.util.Log;
//#508 disabling the stagevideo screen mask, canvas is visible without it.
CONFIG::FLASH_10_1 {
_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);
});
_flowplayer.playlist.onStageVideoStateChange(onStageVideoStateChange);
_flowplayer.playlist.onSeek(function(event:ClipEvent):void {
_flowplayer.playlist.onStageVideoStateChange(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);
}
}
private function onMouseOut(event:MouseEvent):void {
_flowplayer.dispatchEvent(PlayerEvent.mouseOut());
}
......@@ -768,54 +758,51 @@ import org.flowplayer.util.Log;
}
//#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.debug("stage video state changed " + 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;
}
log.info("stage video state changed " + stageVideo);
if (_screenMask.height !== stageVideo.viewPort.height) {
_screenMask.height = stageVideo.viewPort.height;
}
if ( stageVideo ) {
if (_screenMask.x !== stageVideo.viewPort.x) _screenMask.x = stageVideo.viewPort.x;
if (_screenMask.y !== stageVideo.viewPort.y) _screenMask.y = stageVideo.viewPort.y;
_screenMask.width = stageVideo.viewPort.width;
_screenMask.height = stageVideo.viewPort.height;
_screenMask.x = stageVideo.viewPort.x;
_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)) {
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 {
addChildAt(_screenMask, 0);
swapChildren(_screenMask, _copyrightNotice);
swapChildren(_screenMask, _canvasLogo);
}
CONFIG::commercialVersion {
//#75 set the child display list different when a gradient is set.
addChildAt(_screenMask, style.backgroundGradient ? 1 : 0);
}
addChildAt(_screenMask, 0);
//addChildAt(_screenMask, _canvasLogo ? getChildIndex(_canvasLogo) + 1 : 1);
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 {
......
......@@ -4,6 +4,9 @@ Version history:
------
- Upgraded to OSMF 2.0
- #70 Refactored changes with dynamic stream switching features for rtmp and httpstreaming. Switching rules and metrics differ between them.
- Fix for issue caused by #322 with bitrateselect plugin
- #96 possible confusion caused by the naming of the widgets with accessibility options for screen readers. Use the tooltip labels instead
of the widget name if set.
3.2.12
------
......
Version history:
3.2.9
-----
3.2.10
------
- #99 cleanup domain parsing, use native function instead of mx classes.
- #101 fixes for handling origin server redirections.
......
Version history:
3.2.16 (Nov 2013)
-----------------
- #58 fix alignment issue with tooltips. first obtain the global coordinates of the parent to use for configuring the
alignment of the tooltip. outmost left and right tooltips are aligned right and left or else centre them.
3.2.15
------
- #42 when returning and resuming from an instream clip, restart the time update timer.
......
Version history:
3.2.11
3.2.11 (Nov 2013)
------
- New code requires to be compiled against OSMF 2.0
- Now uses OSMF 2.0
- #70 fixes for live streams
- #70 fixes for buffer start value.
......
Version history:
3.2.13 (Nov 2013)
------
- #71 fixes for menu plugin to disable currently selected items to prevent toggling and over states.
When other items are clicked and selected all other items will become enabled.
3.2.12
------
- #36 adjust the menu during fullscreen events as this is prevented once added to the stage.
......
Version history:
3.2.13 (Nov 2013)
-----------------
- #88 fix for bitrate switching updates on metadata change events since changes to the metadata events.
3.2.12
------
- #31 fix to dispatch start events properly when loading new items.
- #88 fix for bitrate switching updates on metadata change events since changes to the metadata events.
3.2.10
-----
......
devkit-dir=../../lib/devkit
osmf-dir=/Users/api/code/osmf/framework/OSMF
osmf-dir=../../lib/osmf/framework/OSMF
#osmf-dir=/Users/api/code/osmf/framework/OSMF
version=3.2.12
\ No newline at end of file
Version history:
3.2.13
3.2.13 (Nov 2013)
------
- #77 for live streams once unpublished, stop the player to prevent streamnotfound errors reconnecting or if the server shuts down.
- #28 fix for live rtmp servers which don't provide metadata needed for red5 and vp6 live streaming, 1500ms should give metadata time if available
3.2.12
------
......
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