Play YouTube videos using Action script 3.0



    And yet, customers are not predictable people!

    You work on the project, you work and everything seems to be fine, and he (the customer) a week before the project is completed: “I want the video to be played on my flash-site. Yes, not simple, but from YouTube. ” Well, what can you do ... Nothing.

    To clarify, I’ll say that the site was made in Flash CS4 using Action Script 3.0.

    However, the task, as it turned out, was not easy. And as always had to get out.



    Thanks for the karma! Moved the article to the Adobe Flex blog.



    Where to begin:



    Looking for articles on a topic of interest? And what pleases those who are , but the trouble, as the author writes, this method no longer works, and the promised update of the article does not yet exist. The task ...

    You can, of course, download the entire player, but since it is written in Action Script 2, you can forget about managing playback. And even such a simple action as scaling a video becomes, unbearably, a difficult task. And so this method also disappears.

    What to do? Work, work and work again "And may you be rewarded for your labors." And so I paint the decision in steps:

    The first step. We get the YouTube player out of the browser cache (in my case, the FireFox browser has the about: cache function).

    Second step.We look at the player’s code using special programs (there are many of them, I use Sothink SWF Decompiler).

    Third step. We are looking for the information we need in numerous classes, namely where and how to take a direct link to the video. From this article, we know that in order to get a direct link to a video, we need to know two things: the video identification number (video_id) and a certain video identification mark (parameter t). With video_id, everything is simple, it is in the video request line http://www.youtube.com/watch?v=lIZVEnyHoGU and is called "v". And here is where to get the “t”, and here the player we’ve taken apart will help us, from which we will find out that there is a certain request to the server with the video ID, in which we get information about it. The request is as followshttp://youtube.com/get_video_info.php?video_id=lIZVEnyHoGU . If you paste this link into the browser line, you will be prompted to download a file called "get_video_info.php". Download and watch the contents of the file. The file contains a line with variables of the form “status = ok & vq = None & author = guylevy ... etc.”. So out of the whole variety of variables we need one, it is called “token” - in fact, this network is the very “t” that we were looking for.

    Step Four We achieved what we wanted - we got a direct link to the video and now, if we add everything we got together http://www.youtube.com/get_video.php?video_id=lIZVEnyHoGU&t= vjVQa1PpcFNnve5gW7h8B51Da_gr8T6BHzSFMbwf6Dw%and, enter into the browser line we will be prompted to download a flv-video with the name “video.flv”, which in turn can be either downloaded or played in your player.

    And so, to complete the third step, we need to download “get_video_info.php” as a text file and get the information we need from it. The “URL.as” class, which I found on one of the forums, helped me in this; it helps to get almost any information from the url, and after my refinement, also encode and decode url with encoded dots, dashes, pluses, etc. d.
    The whole process of obtaining a direct link, I implemented in the class "YouTubeVideoPlayer.as"

    Also using the article about 10 techniques for working with YouTubein the class "YouTubeVideoPlayer.as" you can set the quality of the resulting video, provided that there is one.

    Actually, these are the two classes that will “save the world” :)

    (The above code is written for use in Flex)

    package com
    {
    import flash.events.Event;
    import flash.net.URLLoader;
    import flash.net.URLRequest;

    import mx.controls.VideoDisplay;
    import mx.events.VideoEvent;

    import com.URL;

    /**
    * Класс YouTubeVideoPlayer.
    * @author Aslanyan Tsolak Rubikovich
    * @version 1.0
    */

    public class YouTubeVideoPlayer extends VideoDisplay
    {
    private static var GET_VIDEO :String = "http://www.youtube.com/get_video.php";
    private static var GET_VIDEO_INFO :String = "http://youtube.com/get_video_info.php";
    private static var URL_PREFIX :String = "http://youtube.com?";
    private static var QUALITY0 :String = "";
    private static var QUALITY1 :String = "&fmt=18";
    private static var QUALITY2 :String = "&fmt=22";
    private static var QUALITY3 :String = "&ap=%2526fmt%3D18";
    private static var QUALITY4 :String = "&ap=%2526fmt%3D22";

    private var videoID :String;
    private var videoToken :String;
    private var videoQuality :String;
    private var InfoLoader :URLLoader;

    /**
    * Конструктор.
    * @params source: Строка с идешником вида www.youtube.com/watch?v=lIZVEnyHoGU
    * @params quality: Качество проигрываемого видео [0,1,2,3,4]
    * @return void
    */

    public function YouTubeVideoPlayer(source:String, quality:Number):void
    {
    super();

    videoQuality = DefineQuality(quality);

    LoadVideoInfo(source);
    }

    /**
    * Определяет качество воспроизводимого видео.
    * @params quality: Качество проигрываемого видео [0,1,2,3,4]
    * @return Строку с параметром качества
    */

    private function DefineQuality(quality:Number):String
    {
    switch(quality)
    {
    case 0: return QUALITY0; break;
    case 1: return QUALITY1; break;
    case 2: return QUALITY2; break;
    case 3: return QUALITY3; break;
    case 4: return QUALITY4; break;
    }

    return QUALITY0;
    }

    /**
    * Инициализируе загрузку информации о видео.
    * @params source: Строка с идешником вида www.youtube.com/watch?v=lIZVEnyHoGU
    * @return void
    */

    private function LoadVideoInfo(source:String):void
    {
    videoID = GetVideoID(source);

    var urlRequest :URLRequest = new URLRequest(GET_VIDEO_INFO + "?video_id=" + videoID);

    InfoLoader = new URLLoader();
    InfoLoader.addEventListener(Event.COMPLETE, OnInfoLoaderComplete);
    InfoLoader.load(urlRequest);
    }

    /**
    * Достает из source VideoID.
    * @params source: Строка с идешником вида www.youtube.com/watch?v=lIZVEnyHoGU
    * @return VideoID
    */

    private function GetVideoID(source:String):String
    {
    var _url:URL = new URL(source);

    return _url.query.parsed.v;
    }

    /**
    * Обработчик окончания загрузки get_video_info.php.
    * @return void
    */

    private function OnInfoLoaderComplete(e:Event):void
    {
    InfoLoader.removeEventListener(Event.COMPLETE, OnInfoLoaderComplete);

    var str:String = URL_PREFIX + "?" + e.target.data.toString();

    videoToken = GetVideoToken(str);

    var fullVideoUrl:String = FlvUrlConstruct(videoID, videoToken);

    InitVideoDisplay(fullVideoUrl);
    }

    /**
    * Достает из source videoToken.
    * @params source: Строка с парамеррами из файла get_video_info.php.
    * @return videoToken
    */

    private function GetVideoToken(source:String):String
    {
    var _url:URL = new URL(source);

    return _url.query.parsed.token;
    }

    /**
    * Строит прямую URL к видео.
    * @params video_id: id видео.
    * @params token: id опознавательный знак видео.
    * @return videoToken
    */

    private function FlvUrlConstruct(video_id:String, token:String):String
    {
    var fullUrl:String = GET_VIDEO + "?video_id=" + video_id + "&t=" + token + videoQuality;

    return fullUrl;
    }

    /**
    * Инициализирует VideoDisplay.
    * @params source: ссылка на видео.
    * @return void
    */

    private function InitVideoDisplay(source:String):void
    {
    this.autoPlay = true; // автоматическое начало проигрывания
    this.source = source; // путь к видео
    this.width = 500; // ширина
    this.height = 281.25; // высота
    this.autoRewind = true; // авто перемотка в начало
    this.maintainAspectRatio = true; // задаем способ масштабирования
    this.playheadUpdateInterval = 100; // скорость обнавления VideoEvent.PLAYHEAD_UPDATE
    this.bufferTime = 5; // задаем интервал буферезации

    this.addEventListener(VideoEvent.STATE_CHANGE, StateChange);
    }

    private function StateChange(e:VideoEvent):void
    {
    trace(e.state)
    }
    }
    }


    and another class


    package com
    {
    /**
    * Dschini.org - Manfred Weber
    * manfred.dschini.org
    * manfred.weber (at) gmail dot com
    * Updated Tsolak Aslanyan
    * version 1.1
    */

    public class URL
    {
    private static const PATTERN:RegExp = /^([A-Za-z0-9_+.]{1,8}:\/\/)?([!-~]+@)?([^\/?#:]*)(:[0-9]*)?(\/[^?#]*)?(\?[^#]*)?(\#.*)?/i;

    private var _url :String;
    private var _scheme :String;
    private var _userinfo :String;
    private var _host :String;
    private var _port :String;
    private var _path :String;
    private var _query :String;
    private var _fragment :String;

    /**
    * Create new URL Object
    * @params The url
    */

    function URL(url:String):void
    {
    var result:Array = url.match(URL.PATTERN);

    _url = result[0]; // user:pass@example.com:80/foo/bar.php?var1=foo&var2=bar#abc
    _scheme = result[1]; // http://
    _userinfo = result[2]; // user:pass@
    _host = result[3]; // example.com
    _port = result[4]; // :80
    _path = result[5]; // /foo/bar.php
    _query = result[6]; // ?var1=foo&var2=bar
    _fragment = result[7]; // #abc
    }

    /**
    * Get the url
    */

    public function get url():String
    {
    return _url.length <= 0 ? undefined : _url;
    }

    /**
    * Get the scheme
    */

    public function get scheme():String
    {
    return _scheme.length <= 0 ? undefined : _scheme.substring(0 , _scheme.length - 3);
    }

    /**
    * Get the userinfo
    * Returns an object containing the user and/or password
    */

    public function get userinfo():Object
    {
    var ret:Object = {user:undefined, pass:undefined};

    if(_userinfo)
    {
    var arr:Array = _userinfo.substring(0, _userinfo.length - 1).split(':');

    ret.user = arr[0] ? arr[0] : ret.user;
    ret.pass = arr[1] ? arr[1] : ret.pas;
    }

    return ret;
    }

    /**
    * Get the host
    */

    public function get host():String
    {
    return _host.length <= 0 ? undefined : _host;
    }

    /**
    * Get the port
    */

    public function get port():int
    {
    return _port.length <= 0 ? undefined : int(_port.substring(1, _port.length));
    }

    /**
    * Get the path
    */

    public function get path():String
    {
    return _path.length <= 0 ? undefined : _path;
    }

    /**
    * Get the query
    * Returns an object containing the raw and parsed query string
    */

    public function get query():Object
    {
    var ret:Object = {raw:undefined, parsed:undefined};

    if(_query && _query.length > 0)
    {
    ret.raw = _query;

    var _parse :String = _query.substring(1, _query.length);
    var _intovars :Array = _parse.split("&");

    ret.parsed = _intovars.length > 0 ? {} : undefined;

    for(var i:int = 0; i < _intovars.length; i++)
    {
    var _kv:Array = _intovars[i].split("=");

    ret.parsed[_kv[0]] = _kv[1];
    }
    }
    return ret;
    }

    /**
    * Get the fragment
    */

    public function get fragment():String
    {
    return _fragment.length <= 0 ? undefined : _fragment;
    }

    /**
    * Accepts an encoded string.
    * Returns the decoded string.
    */

    public function Unescape(value:String):String
    {
    return unescape(value);
    }

    /**
    * Accepts an decoded string.
    * Returns the encoded string.
    */

    public function Escape(value:String):String
    {
    return escape(value);
    }
    }
    }


    Here is an example of using classes in Flex Builder:







    import com.YouTubeVideoPlayer;

    private var vp:YouTubeVideoPlayer;

    private function GetVideo():void
    {
    if(vp != null)
    {
    vp.stop();
    vp.close();
    removeChild(vp);
    }

    var vp:YouTubeVideoPlayer = new YouTubeVideoPlayer(utUrl.text, 1);
    vp.x = 119;
    vp.y = 38;
    addChild(vp);
    }
    ]]>









    I hope this article helps someone, or at least seems interesting.

    PS
    Many thanks ayurganov for invite !!!

    PPS
    There is no karma to transfer the topic :(


    Also popular now: