Видео YouTube во Flex

  • Tutorial

Всё описанное ниже работало в далеком 2008 году


В одном из проектов образовалась потребность проигрывать видео с YouTube. И все бы было хорошо, но оказалось, что Data API YouTube не предоставляет прямой ссылки на flv, а дает ссылку на свой проигрыватель с нужным роликом внутри, а еще нужно минимальное управление проигрывателем (передавать в него пару настроек, выполнять старт/стоп/пауза). Правда, плеер YoouTube реализован на ActionScript2, а Flex базируется на ActionScript3, для покорения плеера было придумано:


  • Подгружать ролик в плеере через SWFLoader, использовать Player FlashAPI
  • Создать обертку плеера на ActionScript2, подгрузить туда плеер с роликом, выставить наружу методы управления API через LocalConnections
  • Передать хотябы настройки через flashVars, после придумывать как управлять плеером
  • Загружать плеер в iFrame, писать JavaScript для управления
  • Написать серверный скрипт загрузки flv и проигрывать ролик потоком во время скачивания со своего сервера

Первый способ отпал сразу. Прямой вызов меотодов подгруженного SWFLoader'ом AS2 из AS3 невозможен. Второй способ отпугнул ActionScript2, который с приходом AS3 забыт, как страшный сон, а еще пришлось бы покупать Flash CS. flashVars после пары попыток были отброшены как тупиковый путь. Передавать параметры в url подгружаемой флэшки, какой-то каменный век. iFrame-способ, и при озвучивании кажется тонким извращением… И вроде есть YouTube JavaScript player API, но нужно методы JS вызвать из флекса, а это опять JS-прокладка и головная боль с кроссплатформенностью. Последний вариант был вполне реализуем, но показался не слишком перспективным: нужно научить сервер притворяться браузером, т.е. пройти проверки "на браузерность" ютьюба, а повторенный сегодня алгоритм не факт, что будет работать завтра.


Выход из тупика обозначился после здорового сна и кружки кофе.
Почему нельзя использовать готовый компонент VideoDisplay во флексе? Потому, что нет "прямого" пути к flv на серверах гугла, и в ссылке нужно иметь некий ключ который генерирует YouTube для запросов своего проигрывателя. А где работает плеер ютьюба? В браузере. А где работает флекс? Ага! Тоже в браузере. А ссылка на плеер? Есть! Т.е. можно подгрузить проигрыватель с роликом и разобрать его запросы к серверу YouTube.


Для этого в классе потребуется экземпляр загрузчика


private var _loader:Loader = new Loader();

Нужно отловить событие инициализации загруженного контента, навесить обработчик можно или в конструкторе класса или, как в примере ниже, на обработчик события Flex.INIT, если код находится в mxml-компоненте.


private function onInit(event:FlexEvent):void
{
    // Вешаем обработчик на инициализацию загруженного контента.
    _loader.contentLoaderInfo.addEventListener(Event.INIT, onInitLoader);
}

Метод для начала загрузки плеера, на вход получает ID ролика, строит путь до плеера и отсылает запрос по адресу, youtube.com выполняет хитрый редирект и можно загружать плеер экземпляром в поле _loader (URL плеера с роликом в моем случае получается из YouTube Data API).


private function initLoad(id:String):void
{
    // Формируем адрес плеера с роликом.
    var playerUrl:String = 'http://www.youtube.com/v/' + id;

    // Объект запроса.
    var urlRequest:URLRequest = new URLRequest(playerUrl);
    _loader.load(urlRequest);
}

Как только _loader загрузил плеер, разбираем его параметры URL, в них cодержится все чтобы получить ссылку на flv.


private function onInitLoader(event:Event):void
{
    // Берем все переменные из url полученного плеера
    var urlVars:URLVariables = new URLVariables();
    urlVars.decode(
        // Строку адреса вытаскиваем из лоадера, разбиваем на домен и переменные
        LoaderInfo(event.currentTarget).loader.contentLoaderInfo.url.split("?")[1]
    );

   //Загруженный плеер больше не нужен
   _loader.unload();

    // Теперь в объекте urlVars есть все переменные которые пллер передает на сервер для
    // получения flv, кадра для отображения до начала проигрывания и пр.
    // Передаем id ролика и тот самый ключ для доступа к видео, получаем ссылку.
    var flvURL:String = constructFLVURL(urlVars.video_id, urlVars.t);

    // В переменной flvURL находится ссылка по которой YouTube отдает flv, его теперь можно использовать в своем плеере.
}

Вынесем логику формирования ссылки на flv в отдельный метод.


private function constructFLVURL(video_id:String, t:String):String
{
    // Адрес скрипта, отдающего flv.
    var url:String = "http://www.youtube.com/get_video.php?";
    url += "video_id=" + video_id;
    url += "&t=" + t;
    return url;
}

Вот и все. Можно научить проигрывать ролики с ютьюба любую флешку на AS3, остается вопрос по легальности такого подхода. В соглашении по использованию нет запрета на проигрывание роликов своими плеерами. Может плохо читал?


PS про первый пост

Уф! Как оказалось долго писать посты, может потому, что первый?

Поделиться публикацией
Похожие публикации
Ой, у вас баннер убежал!

Ну. И что?
Реклама
Комментарии 15
  • +5
    Спасибо, отличный первый пост!

    Однажды тоже такое требовалось, но было так лениво, что проще оказалось использовать свой сервер для хранения видео. А готовые решения это всегда очень приятно, вам + :)
    • +1
      Первый пост он трудный самый. Спасибо. :)
      • 0
        Я конечно понимаю, что описанное выше прекрасно работает, поэтому спрошу на всякий случай — обычный способ выдергивания flv из ролика был отвергнут специально? (там же урл формируется простой подстановкой айдишки)
        • 0
          Не понял вопрос. На руках был ответ API ютьюба на запрос параметров ролика, кроме ID ролика никакких специфических ID там не нашел.
          С «обычным способом» не знаком.
          • 0
            Но Download Master как-то выдергивает же ролики.
            • 0
              operafan.net/forum/index.php?action=printpage;topic=3809.0

              там есть код для ютуба
              • 0
                Любопытно. Насколько я понял парсится страничка с роликом, находится строка «var swfArgs = .....», там есть и 'video_id' и 't' и формируется URL с ними. Действительно вполне действенный способ, но мало подойдет для использования во флексе.
                На сервере такой способ действительно был отвергнут, т. к. ютьюб похоже как-то проверяет на то, что к нему обращается браузер (возможно пытается записать куки, возможно, что-то еще). По трудозатратам писать такой имитатор гораздо затратнее чем загрузчик из флекса.
              • –1
                спросите у тут cs.videosaver.ru
            • +2
              Отличный дебют, продолжайте!
              • +1
                После получения flvURL флешку лучше выгрузить от греха подальше _loader.unload();
                а то она пытается с чем-то там соединиться. Спасибо за готовое решение, прикрутим к нашему плееру с вашего позволения.
                • 0
                  Дополнил код, спасибо.
                • 0
                  мне кажется, что вы нарушаете YouTube's Terms of Service.
                  • 0
                    Отвалилось сегодня, пример тоже не работает
                    • +1
                      На ютьюье позавчера были какие-то работы, теперь в url плеера нет ключа для получения flv. Новый способ уже придуман и проверен, как появится свободное время обновлю статью.
                    • 0
                      Зачем столько мучений, если есть TubeLoc — как раз тот самый локал канекшен мост мужду As2 Api YouTube-a в As3 вашего проекта.
                      Подробнее тут:

                      sergiy.habrahabr.ru/blog/72134/

                      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                      Самое читаемое