Получение изображений / видео из XML, отображение каждого в течение определенного промежутка времени - PullRequest
0 голосов
/ 05 июля 2011

Вот концепция этого относительно простого приложения Flash, которое я создаю:

  1. Проверка файла XML на сервере.
  2. Отображение содержимого на основе тегов, независимо от того, является ли тип изображениемили видео.
  3. Каждый имеет значение displayTime.Содержимое должно оставаться только в течение этого долгого времени, а затем перейти к следующему.

Итак, вот мой 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 голосов
/ 06 июля 2011

Я написал что-то очень похожее. Вот рабочий код, вы можете использовать его как есть или изменить его. Повеселись! * Николай

Кстати, клик переключает паузу. К сожалению, 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 / относительно вашего корня src или 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();
        }


    }
}
0 голосов
/ 05 июля 2011

Этот код в настоящее время работает?Похоже, вы слишком много вкладываете в одну функцию - запускаете сразу несколько загрузчиков и используете вложенные функции для обработки результатов.Я не пробовал, но это выглядит немного смущенным.(Я стараюсь держаться подальше от вложенных функций, кстати).

Я бы разбил все это на отдельную цепочку функций.Вам нужна последовательность, которая после загрузки xml:

  1. инициирует загрузку изображения
  2. отвечает на событие загрузки
  3. , затем захватывает изображение как загруженные данные,
  4. добавляет изображение в список отображения, удаляя ранее загруженное изображение
  5. и, наконец, запускает таймер, а при его запуске снова запускает последовательность.

Вам понадобится еще одна функция парсера / контроллера xml, которая обслуживает очередь изображений - она ​​просто проверяет текущее число изображений, увеличивает его и снова запускает последовательность загрузки.

Возможно, вы захотите добавить паруЕще несколько шагов для запуска загрузки графического счетчика во время загрузки, или что-то еще, или каким-то образом связаны с обменом между одной графикой / видео на другую.

Надеюсь, вы поняли as3 и можете понять это отсюда.Дайте мне знать, если у вас есть какие-либо зависания.У меня есть встроенные классы, которые делают именно это, и я могу поделиться, если вам это нужно.

Приветствия

- обновление -

На данный момент, он «работает», как в сценарии, пауза на 5 секунд (с пустым холстом), затем отображает все изображения сразу, а не последовательно

Это потому, что выинициирование всех ваших загрузчиков в одном цикле foreach вместо активации отдельных последовательностей с течением времени.Определенно не то, что вам нужно.

- обработка очереди -

Итак, у вас есть объект xml, который представляет собой просто повторяющуюся структуру данных.Важно отметить, что он имеет свойство длины и может перемещаться как индекс.Чтобы обойти это в цепочечной последовательности, вам, вероятно, понадобится независимая переменная-счетчик, которую вы можете увеличивать / уменьшать.

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 аргумент "direction", который может диктовать _count ++ или _count -;

Довольно просто, но удобно.

Надеюсь, что помогает-

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...