Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Получение переменной из функции (http://www.flasher.ru/forum/showthread.php?t=195284)

Newfag 03.03.2013 21:22

Получение переменной из функции
 
Добрый день уважаемые форумчане. Имеется следующий код:
Код AS3:

var customClient:Object = new Object(); 
customClient.onMetaData = metaDataHandler;
 
function metaDataHandler(infoObject:Object)        {
        var totalTimer:Number = infoObject.duration;
        trace("Общее время "+totalTimer);
 
        return(totalTimer);
        }
 
trace(metaDataHandler(infoObject:Object));

Выводится ошибка 1084: на последней строке (там где trace), якобы выводится скобка перед двоеточием.
Мне нужно любым из способов извлечь значение функции (а именно получить значение infoObject.duration, он же totalTimer). Заранее прошу прощения, если данный вопрос уже поднимался или очевиден. Но я перерыл большую часть faq по flash и перепробовал разные методы подстановки аргументов в последнюю строку, ничего не получается.

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

Zebestov 03.03.2013 22:03

Код AS3:

function metaDataHandler(infoObject:Object):Number        {


Newfag 03.03.2013 23:06

Заменил тип функции на Number - не помогло. Еще пробовал объявлять переменную до функции, вот так
Код AS3:

var totalTimer:Number;
function metaDataHandler(infoObject:Object):Number
{
    totalTimer=infoObject.duration;
        return(totalTimer);
}
trace(totalTimer);

Выводится NaN.

mayakwd 04.03.2013 00:12

Вы пытаетесь отобразить данные до того как они будут получены.

Код AS3:

var totalTimer : Number;
 
function metaDataHandler (infoObject : Object) : void {
  totalTimer = infoObject.duration;
  trace(totalTimer);
}

вы получаете данные только в момент когда вызывается metaDataHandler, и только после этого можете отобразить эти данные.

Wolsh 04.03.2013 00:17

Цитата:

trace(metaDataHandler(infoObject:Object));
Выводится ошибка 1084: на последней строке (там где trace), якобы выводится скобка перед двоеточием.
Уберите объявление типа параметра из ВЫЗОВА

Newfag 04.03.2013 14:39

mayakwd, в том то и дело, что нужно вывести переменную (totalTimer) за пределы этой функции, чтобы потом использовать в другой функции.
Возможно есть способ объявить переменную, затем внести в нее значение (в функции), а затем вывести (в другой функции).

Добавлено через 6 минут
Wolsh,
Код AS3:

trace(metaDataHandler(infoObject));

Обращение не существующего свойства infoObject.

Убирая тип параметра из самой функции получаем то же самое.

dimensb 04.03.2013 15:28

1. Как вам ранее сказали, при вызове функции нельзя добавлять определение тип ее параметра (:Object)
2. Вы передаете несуществующий объект, сначала вам надо создать его, а потом использовать

Код AS3:

var customClient:Object = new Object(); 
customClient.onMetaData = metaDataHandler;
 
var infoObject:Object = {duration: 0};
 
function metaDataHandler(infoObject:Object)       
{
        var totalTimer:Number = infoObject.duration;
        trace("Общее время "+totalTimer);
 
        return(totalTimer);
}
 
trace(metaDataHandler(infoObject));


Newfag 04.03.2013 15:52

Выводится
Код AS3:

Общее время 0
0
Общее время 203.603

Изменив 0 на любое другое число при создании объекта infoObject, получаю это число. Т.е.
Код AS3:

var infoObject:Object = {duration: 1};

дает
Код AS3:

Общее время 1
1
Общее время 203.603


Wolsh 04.03.2013 15:59

Путешествия в будущее еще не придумали.
Вы реально думаете, что можно вызвать функцию и узнать, каким будет некое значение через полчаса?
Вы еще не получили infoObject. Его НЕТ. Как Вы можете узнать infoObject.duration?

dimensb 04.03.2013 16:03

Итак, вы передали объект в функцию, но ничего с ним не сделали и не обновили его значение. Поэтому выводится именно то значение, которым он был инициализирован, в ваших случаях 0 и 1. Это верно. Если вы хотите чтобы там было другое значение, вам стоит его обновить внутри функции, например так

Код AS3:

infoObject.duration = 10;

или заменить число 10 на любой другое значение или источник.

Newfag 04.03.2013 16:03

Какие путешествия в будущее? Я просто хочу узнать длительность ролика в секундах. И всего лишь использовать это значение в простом математическом выражении.

dimensb 04.03.2013 16:06

Какого ролика? Какой формат, как вы его загружаете?

Newfag 04.03.2013 16:11

dimensb, загружаю так:

Код AS3:

var nc:NetConnection = new NetConnection(); 
nc.connect(null);
var ns:NetStream = new NetStream(nc);
ns.addEventListener(NetStatusEvent.NET_STATUS,netStatusHandler);
 
function netStatusHandler(event:NetStatusEvent):void
{
    // handle netStatus events, described later
}
 
 
ns.client = customClient;
 
 
ns.play("video.flv");
vid.attachNetStream(ns);

Формат - flv.

dimensb 04.03.2013 16:32

Да, вы действительно путешествуете в будущее ;)

Дело в том что ns вызовет обработчик onMetaData объекта customClient только когда получит метаданные.
Когда вы пытаетесь вызвать его самостоятельно, таких данных у вас нет, поэтому вы и получали сообщение об ошибке. Ниже приведен рабочий пример (нарезан из разных примеров из интернет)

Код AS3:

package
{
        import flash.media.Video;
        import flash.net.NetConnection;
        import flash.net.NetStream;
 
        public class Test extends Sprite
        {
                public function Test()
                {
                        var vid:Video = new Video(320, 240);
                        addChild(vid);
 
                        var nc:NetConnection = new NetConnection();
                        nc.connect(null);
 
                        var ns:NetStream = new NetStream(nc);
                        vid.attachNetStream(ns);
 
                        var listener:Object = new Object();
                        listener.onMetaData = onMetaData;
                        ns.client = listener;
 
                        // Первое попавшееся видео в формате flv
 
                        ns.play("http://www.mediacollege.com/video-gallery/testclips/barsandtone.flv");
                }
 
                // Будет вызвана автоматически
 
                function onMetaData(metadata:Object):void
                {
                        var lengthOfVideo:Number = int(metadata.duration * 1000)+1;
                        trace("Length of flv from metadata = " + lengthOfVideo);
                }
      }
}


Newfag 04.03.2013 16:50

Спасибо за код, но я все равно не могу использовать metadata.duration. Понимаете, мне нужно использовать это число в другой функции.

Добавлено через 2 минуты
кстати, еще в пакете добавил
Код AS3:

         import flash.display.*;

и
Код AS3:

public class Test extends MovieClip

(вместо Sprite). Это если у кого код будет ошибки выдавать.

dimensb 04.03.2013 16:56

Вы можете:

1. Вызвать функцию непосредственно в обработчике onMetaData
Код AS3:

function yourProcedure(duration:Number):void
{
        trace(duration);
}
 
function onMetaData(metadata:Object):void
{
        var lengthOfVideo:Number = int(metadata.duration * 1000)+1;
        trace("Length of flv from metadata = " + lengthOfVideo);
        yourProcedure(lengthOfVideo);
}

2. Сохранить значение в этой функции и использовать его позднее (или добавить его в массив, если нужна история значений)
Код AS3:

 
private var lastDuration:Number;
 
function onMetaData(metadata:Object):void
{
        var lengthOfVideo:Number = int(metadata.duration * 1000)+1;
        trace("Length of flv from metadata = " + lengthOfVideo);
        lastDuration = lengthOfVideo;
}

Как бы то ни было, вы должны понимать что это значение будет доступно только после того, как выполнится обработчик onMetaData.

Newfag 04.03.2013 17:12

А как понять когда метаданные пришли и обработчик уже выполнился? Пробовал:
Код AS3:

if(isPlaying){
trace(lastDuration);
}
 
NaN

Добавлено через 7 минут
Однако первый способ, с вызовом функции в обработчике работает, но очень, очень хотелось бы второй, с выводом в переменную.

dimensb 04.03.2013 17:30

Это асинхронный вызов и с этим ничего не поделать. Ваша процедура должна реагировать на изменение этого значения. То есть общая логика, используя словесное описание, должна быть такой:

Основная часть
1. Создать компоненты для загрузки flv, подключить обработчики.
2. Запросить flv.
Все, дальше надо ждать.

Обработчик
1. Получить длительность
2. Выполнить необходимый код

Если вам по какой-то причине не подходит вызов внутри onMetaData, то вы можете послать свое сообщение, например так (впрочем это масло масляное)

Код AS3:

package
{
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.media.Video;
        import flash.net.NetConnection;
        import flash.net.NetStream;
 
        public class TestNc extends Sprite
        {
                private static const METADATA_OBTAINED_EVENT_STR:String = "METADATA_OBTAINED";
 
                private var duration:Number;
 
                public function TestNc()
                {
                        var vid:Video = new Video(320, 240);
                        addChild(vid);
 
                        var nc:NetConnection = new NetConnection();
                        nc.connect(null);
 
                        var ns:NetStream = new NetStream(nc);
                        vid.attachNetStream(ns);
 
                        var listener:Object = new Object();
                        listener.onMetaData = onMetaData;
                        ns.client = listener;
 
                        addEventListener(METADATA_OBTAINED_EVENT_STR, onMetaDataObtained);
 
                        // Первое попавшееся видео в формате flv
 
                        ns.play("http://www.mediacollege.com/video-gallery/testclips/barsandtone.flv");
                }
 
                // Будет вызвана автоматически
 
                private function onMetaData(metadata:Object):void
                {
                        duration = metadata.duration;
                        dispatchEvent(new Event(METADATA_OBTAINED_EVENT_STR));
                }
 
                private function onMetaDataObtained(e:*)
                {
                        trace(duration);
                }
        }
}


Newfag 04.03.2013 17:46

Большое спасибо всем, кто отписался в этом топике за помощь, отдельная благодарность dimensb.


Часовой пояс GMT +4, время: 00:53.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.