从XML获取图像/视频,在一定时间内显示每个图像/视频

时间:2011-07-05 17:07:18

标签: flash actionscript-3 actionscript

以下是我正在构建的这个相对简单的Flash应用程序的概念:

  1. 检查服务器上的XML文件。
  2. 根据标签显示内容,无论类型是图片还是视频。
  3. 每个都有一个displayTime值。内容应该只保持这么长时间,然后再继续下去。
  4. 所以这是我的XML文件:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <livefeed>
    
        <timeUpdated string="121213" />
    
        <content type="image" url='image01.jpg' displayTime="5" />
        <content type="image" url='image02.jpg' displayTime="5" />
        <content type="image" url='image03.jpg' displayTime="5" />
    
    </livefeed>
    

    这里有一点我的ActionScript 3:

    function onload(e:Event):void {
        var xml:XMLList = new XMLList(xmlholder.data);
        var xmlContent:XMLList = xml.content;
        if(xml.timeUpdated.@string != currentTimeUpdated) {
            currentTimeUpdated = xml.timeUpdated.@string;
    
            for each (var content:XML in xmlContent) {
                if (content.@type == 'image') {
                    var myImageLoader:Loader = new Loader();
                    var imageURLRequest:URLRequest = new URLRequest(content.@url);
    
                    myImageLoader.load(imageURLRequest);
                    myImageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, imageLoaded);
    
                    function imageLoaded(e:Event):void {                                
                        var newTimer:Timer = new Timer(content.@displayTime * 1000); // update every 10 seconds
                        newTimer.start();
                        newTimer.addEventListener(TimerEvent.TIMER, addImage);
    
                        function addImage(e:TimerEvent):void {
                            addChild(myImageLoader);
                        }
    
                    } 
                }
            }
        }
    }
    

    所以它不适合我,因为我想要它。我知道我错了但不知道怎么做。我真的希望它只显示内容,暂停,转到下一个内容,暂停,然后循环。

    关于我应该如何做或者如何改进的任何想法/建议?

    谢谢!

2 个答案:

答案 0 :(得分:0)

此代码目前有效吗?你似乎过多地投入到一个函数中 - 一次运行一堆加载器,并使用嵌套函数来处理结果。我没试过,但看起来有点困惑。 (我试着远离嵌套函数,顺便说一句)。

我会把所有这些都分解成一个单独的函数链。一旦加载了xml,你需要一个序列:

  1. 启动图片加载
  2. 响应加载事件
  3. 然后将图像捕获为已加载的数据,
  4. 将图像添加到显示列表中,删除以前加载的图像
  5. 最后,启动计时器,当它启动时,再次启动序列。
  6. 您将需要另一个xml解析器/控制器函数来处理图像队列 - 这只是检查当前图像计数,递增它并再次发起加载序列。

    您可能需要添加几个步骤来在加载运行时运行加载微调器图形,或者以某种方式处理从一个图形/视频到下一个图形/视频的交换。

    希望你已经掌握了as3并且可以从这里解决这个问题。如果你有任何挂断,请告诉我。我确实已经完成了所有这些的完整课程,如果你需要,我可以分享。

    干杯

    - 更新 -

      

    现在,它在脚本中“起作用”   暂停5秒钟(空白   canvas),然后显示所有图像   立刻而不是顺序

    这是因为您在一个foreach循环中启动所有加载器,而不是随着时间的推移激活单个序列。绝对不是你想要的。

    - 队列处理 -

    所以,你有你的xml对象,它只是一个重复的数据结构。重要的是,它具有length属性,可以作为索引导航。要在链接序列中遍历它,您可能需要一个可以递增/递减的独立计数器变量。

    private var _count:uint = 0;
    
    private function controlQueue(){
    
        var target: String = xmlContent[_count].@url; //or however you are obtaining this
        initiateLoad(target);
    
        _count++: //increment counter
    
        if(_count > xmlContent.length){ _count = 0}; //if counter exceeds length, swing back around
    }
    
    private function initiateLoad(target:String){ ...
    

    如果您允许用户控制,那么您可以向controlQueue传递一个“方向”参数,该参数可以指示_count ++或_count - ;

    非常简单,但很方便。

    希望有所帮助 -

答案 1 :(得分:0)

我写了一些非常相似的东西。这是工作代码,您可以按原样使用它或更改它。玩得开心! *尼古拉斯

顺便说一句,点击切换暂停。不幸的是,loadPrevious()没有实现。只需复制并更改loadNext()方法

即可

这样的事情应该有效。如果你想要一个反向循环

// load Previous
if(__currentIndex>1){
    __currentIndex--;
}else{
    __currentIndex=__xml.child("image").length()-1;
}

这是演示类(如何使用ImageSlideshow)

package
{
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import de.goldsource.display.ImageSlideshow;

    public class Demo extends Sprite
    {

        public function Demo()
        {

            // setup
            stage.scaleMode=StageScaleMode.NO_SCALE;
            stage.align=StageAlign.TOP_LEFT;
            var xml:XML =   <slideshow>
                                <image src='assets/img1.jpg' delay="0.1" />
                                <image src='assets/img2.jpg' delay="0.1" />
                                <image src='assets/img3.jpg' delay="0.1" />
                            </slideshow>;
            ImageSlideshow.DEBUG = true;
            addChild(new ImageSlideshow(xml));          
        }
    }
}

幻灯片课程。您可以使用它并更改它,但保留许可证文本。该软件包是de.goldsource.display将此代码保存在名为ImageSlideshow.as的文件中,并将其放在de / goldsource / display / relative到src root或lib目录中。

package de.goldsource.display
{
    import flash.display.Bitmap;
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.MouseEvent;
    import flash.events.TimerEvent;
    import flash.net.URLRequest;
    import flash.system.System;
    import flash.utils.Timer;
    import flash.utils.setTimeout;

    /**
     * 
     * <p>
     * <b>License</b>
     * <br/>
     * <a href="http://www.opensource.org/licenses/mit-license.php">based on The MIT License (MIT)</a>
     * </p>
     * <p>
     * Copyright (c) 2011 Nicholas Schreiber
     * </p>
     * <p>
     * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
     * </p>
     * <p>
     * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
     * </p>
     * <p>
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     * </p>
     * 
     * @author Nicholas Schreiber
     * */
    public class ImageSlideshow extends Sprite
    {

        /**
         * Traces Memory Usage Info
         * */
        public static var DEBUG:Boolean = false;

        /**
         * Slideshow data
         */
        private var __xml:XML;

        /**
         * Main Timer
         * */
        private var __timer:Timer = new Timer(1000);

        /**
         * True if paused
         * */
        private var __paused:Boolean = false;

        /**
         * Current Element
         * */
        private var __currentIndex:int=-1;


        /**
         * loads the images
         * */
        private var __loader:Loader;

        /**
         * True if Loader has done its job
         * */
        private var __loaderReady:Boolean=true;

        /**
         * Error Count
         * */
        private var __errorCount:uint = 0;

        /**
         * Only for Debug Purposes
         * */
        private var __lastMemoryMax:uint = 0;

        /**
         * ImageSlideshow - Loads and displays Images
         * 
         * <p>
         * jpg, gif or png possible<br/>
         * delay in seconds
         * </p>
         * <p>
         * <code>
         * &lt;slideshow&gt;<br/>
         * &lt;image src='assets/img1.jpg' delay="0.1" /&gt;<br/>
         * &lt;image src='assets/img2.png' delay="2" /&gt;<br/>
         * ...<br/>
         * &lt;image src='assets/imgN.gif' delay="0.1" /&gt;<br/>
         * &lt;/slideshow&gt;<br/>
         * </code>
         * </p> 
         * @param $xml some XML as described above
        * */
        public function ImageSlideshow($xml:XML=null)
        {   
            __xml = $xml;       
            __loader = new Loader();

            // Click toggles Pause
            addEventListener(MouseEvent.CLICK,__onClick);

            // The Update Interval
            __timer.addEventListener(TimerEvent.TIMER,__onTimer);

            // load the first image
            loadNext();
        }

        /**
         * Toggle Pause
         * */
        public function togglePause():void{
            if(__paused){
                __paused = false;
            }else{                              
                __paused = true;
            }
            __updateTimerStatus();
        }

        /**
         * loadNext Image (looped)
         * */
        public function loadNext():void{            
            // return if not possible
            if(!__loaderReady || __xml == null)return;  

            // loader is blocked
            __loaderReady = false;  

            // load Next
            if(__currentIndex<__xml.child("image").length()-1){
                // slides availabe
                __currentIndex++;
            }else{
                // no more slides, looping the slideshow...
                __currentIndex=0;
            }   

            // resetting timer
            __timer.stop();
            __timer.reset();
            // setting delay
            __timer.delay = __xml.child("image")[__currentIndex].@delay*1000;

            // setup loader
            __loader.contentLoaderInfo.addEventListener(Event.COMPLETE, __onLoadComplete);
            __loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,__onIOError);

            // load
            __loader.load(new URLRequest(__xml.child("image")[__currentIndex].@src));               
        }

        /**
         * toggles Pause on Click
         * */       
        private function __onClick($e:MouseEvent):void{
            togglePause();
        }

        /**
         * starts the timer if possible or stops it if paused
         * */
        private function __updateTimerStatus():void{    
            if(!__loaderReady)return;
            if(__paused && __timer.running){
                __timer.stop();
            }else{                              
                __timer.start();
            }

        }

        /**
         * Invoked by the timer
         * */
        private function __onTimer(e:TimerEvent):void{
            loadNext();
        }       

        /**
         * Invoked if image is not existent (wrong src url!)
         * */
        private function __onIOError(e:IOErrorEvent):void{          
            // remove listeners
            __loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, __onLoadComplete);   
            __loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR,__onIOError);                      

            // iterate error count, will stop the app when > 10 in a row
            __errorCount ++;            
            trace("Image could not be loaded "+__errorCount +" of 10 attempts");


            if(__errorCount > 10)return;

            // if more than one image in list try next
            __loaderReady = true;
            if(__xml.child("image").length()>1)loadNext();          
        }

        /**
         * Invoked when image is loaded
         * */
        private function __onLoadComplete(e:Event):void{    
            // remove the listeners
            __loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, __onLoadComplete);   
            __loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR,__onIOError);

            // reset the error count, cause on image was loaded successful
            __errorCount = 0;

            // add the loaded image to the display
            addChild(__loader.content); 

            // yes the loader is no longer blocked
            __loaderReady = true;

            // restarts the timer if was running
            __updateTimerStatus();

            // removes 
            __cleanUp();
        }

        /**
         * Removes all unnecessary Bitmaps
         * */
        private function __cleanUp():void{
            // leave method if nothing to do (only one object on screen)
            if(numChildren==1)return;   

            /*  
                never forget to dispose() a bitmap you want to get rid of,
                otherwise FlashPlayer will not remove it from the RAM
                removing and disposing within one line
            */
            if(getChildAt(0) is Bitmap)Bitmap(removeChildAt(0)).bitmapData.dispose();

            // Debug mode only
            if(!DEBUG)return;
            if(__lastMemoryMax<System.totalMemory){
                trace("New Memory Peak "+((__lastMemoryMax= System.totalMemory)/Math.pow(1024,2)).toFixed(2)+" MB");
            }           
        }

        /**
         * xml Getter / Setter - Slideshow data
         * <p>
         * jpg, gif or png possible<br/>
         * delay in seconds
         * </p>
         * <p>
         * <code>
         * &lt;slideshow&gt;<br/>
         * &lt;image src='assets/img1.jpg' delay="0.1" /&gt;<br/>
         * &lt;image src='assets/img2.png' delay="2" /&gt;<br/>
         * ...<br/>
         * &lt;image src='assets/imgN.gif' delay="0.1" /&gt;<br/>
         * &lt;/slideshow&gt;<br/>
         * </code>
         * </p>
         * 
         * @param value XML
         * @return XML
         * */
        public function get xml():XML
        {
            return __xml;
        }

        public function set xml(value:XML):void
        {
            __xml = value;
            __currentIndex = -1;
            loadNext();
        }


    }
}