Commit 97e807a7 authored by Aaron Wells's avatar Aaron Wells
Browse files

Upgrade flowplayer.audio to version 3.2.11

Bug 1316372: Also removing the flowplayer.audio source files, because
they're not necessary to run Mahara, and we don't build it ourselves
anyway.

Change-Id: Ib64dbec723092486860a2fb37099b7918cfcb6a4
parent b19a318b
......@@ -2,7 +2,7 @@ Flowplayer in Mahara
=====================
Website: http://flowplayer.org/plugins/streaming/audio.html
Version: 3.2.2
Version: 3.2.11
This flash mp3 player is used by the internal media blocktype.
......
Version history:
3.2.10
------
- #575 send the start event after begin
- #569 if the playlist has been reset but the audio has been already buffered, set the duration and start event.
- #582 fixes for metadata events dispatching in playlists and when replaying same audio item, cleanup duration updating once download has completed,
fixes for clearing the previous cover image display.
- #611 close the channel and sound on stream not found errors.
- #614 fixes for auto buffering issues where a sound channel may not be active yet.
3.2.9
-----
- #501 fixes to dispatch start state correctly.
- #501 use the sound channel to listen for a complete event to finish correctly.
3.2.8
-----
Fixes:
- fixed to dispatch onStart only once
- the duration is now available in the clip when onStart is dispatched
- audio duration was estimated to be too long, issue #323
- duration not available in the onMetaData event, issue #278
- now dispatches error 200 when the mp3 URL does not respond, issue #334
- #428 regression issue calculating the initial duration, was returning too small for the duration tracker.
- #428 when fully downloaded ID3 is resent and update the duration.
- #475 if we have a clip duration set, dispatch start or else wait until the duration is estimated. Start required for beginning duration tracker.
3.2.3
-----
Fixes:
- Fixed to dispatch onStart when the mp3 file does not contain a id3 tag
- Now uses baseUrl if that is given
3.2.2
-----
Fixes:
......
version=3.2.2
devkit-dir=../flowplayer.devkit
\ No newline at end of file
<project name="Audio plugin for flowplayer" default="deploy">
<property file="build.generated.properties"/>
<property file="${user.home}/plugin.properties" />
<property file="build.properties" />
<property file="${devkit-dir}/plugin-build.properties" />
<import file="${devkit-dir}/plugin-build.xml"/>
<property name="flowplayer_lib" value="${devkit-dir}/flowplayer.swc" />
<property name="basename" value="flowplayer.audio" />
<property name="releasedir" value="flowplayer.audio" />
<property name="plugin-binary" value="${basename}.swf" />
<property name="plugin-binary-versioned" value="${basename}-${version}.swf" />
<property name="plugin-swc" value="${basename}.swc" />
<property name="plugin-main-class" value="org/flowplayer/audio/AudioProviderFactory.as" />
<target name="release" description="makes a release" depends="build">
<copyrelease targetdir="flowplayer.audio">
<releasefiles>
<fileset dir="${build-dir}">
<include name="${plugin-binary-versioned}"/>
</fileset>
</releasefiles>
</copyrelease>
</target>
</project>
\ No newline at end of file
/* * Copyright (c) 2008-2011 Flowplayer Oy * * This file is part of FlowPlayer. * * FlowPlayer is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * FlowPlayer is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with FlowPlayer. If not, see <http://www.gnu.org/licenses/>. */ package org.flowplayer.audio { import flash.display.DisplayObject; import flash.display.Loader; import flash.events.Event; import flash.events.IOErrorEvent; import flash.events.ProgressEvent; import flash.events.TimerEvent; import flash.media.ID3Info; import flash.media.Sound; import flash.media.SoundChannel; import flash.media.SoundLoaderContext; import flash.net.NetConnection; import flash.net.NetStream; import flash.net.URLRequest; import flash.utils.Dictionary; import flash.utils.Timer; import org.flowplayer.controller.ClipURLResolverHelper; import org.flowplayer.controller.ConnectionProvider; import org.flowplayer.controller.ResourceLoader; import org.flowplayer.controller.StreamProvider; import org.flowplayer.controller.TimeProvider; import org.flowplayer.controller.VolumeController; import org.flowplayer.model.Clip; import org.flowplayer.model.ClipEvent; import org.flowplayer.model.ClipEventType; import org.flowplayer.model.DisplayProperties; import org.flowplayer.model.Playlist; import org.flowplayer.model.Plugin; import org.flowplayer.model.PluginEventType; import org.flowplayer.model.PluginModel; import org.flowplayer.util.Log; import org.flowplayer.view.Flowplayer; /** * @author api */ public class AudioProvider implements StreamProvider, Plugin { private var log:Log = new Log(this); private var _sound:Sound; private var _playing:Boolean; private var _paused:Boolean; private var _durationSeconds:Number; private var _clip:Clip; private var _pausedPosition:Number; private var _channel:SoundChannel; private var _playlist:Playlist; private var _progressTimer:Timer; private var _seeking:Boolean; private var _started:Boolean; private var _volumeController:VolumeController; private var _pauseAfterStart:Boolean; private var _bufferFullDispatched:Boolean; private var _timeProvider:TimeProvider; private var _model:PluginModel; private var _lastDurationDispatched:Number = 0; private var _imageLoader:ResourceLoader; private var _imageDisplay:Loader = null; private var context:SoundLoaderContext; private var _screen:DisplayProperties; private var _clipUrlResolverHelper:ClipURLResolverHelper; public function stopBuffering():void { closeSound(); resetState(); } public function stop(event:ClipEvent, closeStream:Boolean = false):void { seek(null, 0); if (_channel) { log.debug("in stop(), stopping channel"); _channel.stop(); } if (closeStream) { closeSound(); } resetState(); if (event && _clip) { _clip.dispatchEvent(event); } } private function closeSound():void { try { _sound.close(); } catch (e:Error) { // ignore } } private function resetState():void { _playing = false; _paused = false; _started = false; _bufferFullDispatched = false; _durationSeconds = 0; _pausedPosition = 0; if (_progressTimer) { _progressTimer.stop(); } } public function attachStream(video:DisplayObject):void { } private function doLoad():void { } public function load(event:ClipEvent, clip:Clip, pauseAfterStart:Boolean = true):void { log.debug("load()"); resetState(); if (_clip == clip) { log.debug("load() reusing existing sound object"); addListeners(_sound); play(0); _clip.dispatch(ClipEventType.BEGIN); _clip.dispatch(ClipEventType.START); } else { log.debug("load() creating new sound object"); _clip = clip; _sound = new Sound(); context = new SoundLoaderContext(1000, true); if (clip.getCustomProperty("coverImage")) { var cover:Object = getCoverImage(clip); log.debug("Loading Artwork For Audio " + cover.url); // _imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageComplete); // _imageLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onImageError); _imageLoader.load(cover.url, onImageComplete); } else { playAudio(); } } _pauseAfterStart = pauseAfterStart; } private function getCoverImage(clip:Clip):Object { var cover:Object = clip.getCustomProperty("coverImage"); if (cover is String) return { url: "" + cover }; if (cover.hasOwnProperty("scaling")) { _clip.setScaling(cover["scaling"]); } return cover; } private function playAudio():void { addListeners(_sound); _clipUrlResolverHelper.resolveClipUrl(_clip, function onClipUrlResolved(clip:Clip):void { _sound.load(new URLRequest(clip.url), context); play(0); }); } private function onImageError(error:IOErrorEvent):void { log.debug("Cover artwork doesn't exist playing now"); playAudio(); } private function onImageComplete(loader:ResourceLoader):void { log.debug("Cover image loaded playing now"); _imageDisplay = loader.getContent() as Loader; _clip.originalWidth = _imageDisplay.width; _clip.originalHeight = _imageDisplay.height; playAudio(); } private function addListeners(sound:Sound):void { sound.addEventListener(ProgressEvent.PROGRESS, onProgress); sound.addEventListener(Event.SOUND_COMPLETE, onComplete); sound.addEventListener(IOErrorEvent.IO_ERROR, onIoError); sound.addEventListener(Event.ID3, onId3); _progressTimer = new Timer(200); _progressTimer.addEventListener(TimerEvent.TIMER, onProgressTimer); _progressTimer.start(); } private function onIoError(event:IOErrorEvent):void { log.error("Unable to load audio file: " + event.text); //dispatching this error causes crashes in Safari: // _clip.dispatch(ClipEventType.ERROR, "Unable to load audio file: " + event.text); } private function addId3Metadata():void { var metadata:Object = new Object(); try { var tag:ID3Info = _sound.id3; } catch (e:Error) { log.warn("unable to access ID3 tag: " + e); } for (var prop:String in tag) { log.debug(prop + ": " + _sound.id3[prop]); metadata[prop] = _sound.id3[prop]; } _clip.metaData = metadata; } private function onId3(event:Event):void { log.debug("onId3(), _started == " + _started); addId3Metadata(); if (_started) return; log.debug("dispatching START"); _clip.dispatch(ClipEventType.METADATA); _clip.dispatch(ClipEventType.START); _started = true; if (_pauseAfterStart) { pause(new ClipEvent(ClipEventType.PAUSE)); } } private function onProgress(event:ProgressEvent):void { if (_playing) return; _playing = true; _clip.dispatch(ClipEventType.BEGIN); if (!_clip.metaData) { _clip.dispatch(ClipEventType.START); } } private function onProgressTimer(event:TimerEvent):void { estimateDuration(); if (! _sound.bytesTotal > 0) return; if (! _sound.bytesLoaded > 0) return; if(_sound.isBuffering == true && _sound.bytesTotal > _sound.bytesLoaded) { _clip.dispatch(ClipEventType.BUFFER_EMPTY); } else if (! _bufferFullDispatched){ _clip.dispatch(ClipEventType.BUFFER_FULL); _bufferFullDispatched = true; } } private function estimateDuration():void { var durationSecs:Number = (_sound.length/(_sound.bytesLoaded/_sound.bytesTotal))/1000; if (Math.abs(_lastDurationDispatched - durationSecs) >= 0.5) { _lastDurationDispatched = durationSecs; log.debug("dispatching onDuration(), " + durationSecs); _model.dispatch(PluginEventType.PLUGIN_EVENT, "onDuration", durationSecs); } _clip.durationFromMetadata = durationSecs; } private function onComplete(event:Event):void { // dispatch a before event because the finish has default behavior that can be prevented by listeners _clip.dispatchBeforeEvent(new ClipEvent(ClipEventType.FINISH)); } public function getVideo(clip:Clip):DisplayObject { log.debug("getVideo() " + _imageDisplay); return _imageDisplay; } public function resume(event:ClipEvent):void { log.debug("resume"); _paused = false; play(_pausedPosition); if (event) { _clip.dispatchEvent(event); } } public function pause(event:ClipEvent):void { log.debug("pause"); _paused = true; _pausedPosition = _channel.position; _channel.stop(); if (event) { _clip.dispatchEvent(event); } } public function seek(event:ClipEvent, seconds:Number):void { if (! _channel) return; _channel.stop(); _seeking = true; play(seconds * 1000); if (event && _clip) { _clip.dispatchEvent(event); } if (_paused) { _pausedPosition = _channel.position; _channel.stop(); } } private function play(posMillis:Number):void { _channel = _sound.play(posMillis, 0); _volumeController.soundChannel = _channel; } public function get stopping():Boolean { return false; } public function get allowRandomSeek():Boolean { return false; } public function get bufferStart():Number { return 0; } public function get playlist():Playlist { return _playlist; } public function get time():Number { if (_timeProvider) { return _timeProvider.getTime(null); } return _channel ? _channel.position / 1000 : 0; } public function get bufferEnd():Number { return _sound && _clip ? _sound.bytesLoaded / _sound.bytesTotal * _clip.duration : 0; } public function get fileSize():Number { return _sound ? _sound.bytesLoaded : 0; } public function set playlist(playlist:Playlist):void { _playlist = playlist; } public function set netStreamClient(client:Object):void { } public function set volumeController(controller:VolumeController):void { _volumeController = controller; } public function onConfig(model:PluginModel):void { _model = model; model.dispatchOnLoad(); } public function getDefaultConfig():Object { return null; } public function onLoad(player:Flowplayer):void { _imageLoader = player.createLoader(); _screen = player.pluginRegistry.getPlugin("screen") as DisplayProperties; _clipUrlResolverHelper = new ClipURLResolverHelper(player, this); } public function addConnectionCallback(name:String, listener:Function):void { } public function addStreamCallback(name:String, listener:Function):void { } public function get netStream():NetStream { return null; } public function get netConnection():NetConnection { return null; } public function getDefaultConnectionProvider():ConnectionProvider { return null; } public function set timeProvider(timeProvider:TimeProvider):void { _timeProvider = timeProvider; } /** * the value of this property is "audio" */ public function get type():String { return "audio"; } public function switchStream(event:ClipEvent, clip:Clip, netStreamPlayOptions:Object = null):void { } public function get streamCallbacks():Dictionary { return null; } } }
\ No newline at end of file
/* * Copyright (c) 2008-2011 Flowplayer Oy * * This file is part of FlowPlayer. * * FlowPlayer is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * FlowPlayer is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with FlowPlayer. If not, see <http://www.gnu.org/licenses/>. */ package org.flowplayer.audio { import org.flowplayer.model.PluginFactory; import flash.display.Sprite; /** * @author api */ public class AudioProviderFactory extends Sprite implements PluginFactory { public function newPlugin():Object { return new AudioProvider(); } }}
\ No newline at end of file
......@@ -244,7 +244,7 @@ class PluginBlocktypeInternalmedia extends PluginBlocktype {
$url = self::get_download_link($artefact, $block);
$params = array('play' => 'true');
$html = '<a href="' . $url . '">' . hsc($artefact->get('title')) . '</a><br>
<span class="blocktype_internalmedia_mp3" id="' . $id . '">('
<span class="blocktype_internalmedia_mp3" id="' . $id . '">('
. get_string('flashanimation', 'blocktype.file/internalmedia') . ')</span>
<script type="text/javascript">
var so = new SWFObject("' . $url . '","player","' . $width . '","' . ($height + 20). '","7");
......@@ -290,7 +290,7 @@ class PluginBlocktypeInternalmedia extends PluginBlocktype {
$type = 'type: "audio",'; // force the player to use the audio plugin
$buffering = 'false'; // without this autoPlay will also be set to true
$audio = ', audio: {
url: "' . $baseurl . 'flowplayer.audio/flowplayer.audio-3.2.2.swf"
url: "' . $baseurl . 'flowplayer.audio/flowplayer.audio-3.2.11.swf"
}';
}
......@@ -436,7 +436,7 @@ class PluginBlocktypeInternalmedia extends PluginBlocktype {
}
private static function get_download_link(ArtefactTypeFile $artefact, BlockInstance $instance, $wmp=false) {
return get_config('wwwroot') . 'artefact/file/download.php?file='
return get_config('wwwroot') . 'artefact/file/download.php?file='
. $artefact->get('id') . '&view=' . $instance->get('view')
. ($wmp ? '&download=1' : '');
}
......
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