それでも、顧客は予測可能な人ではありません!
あなたはプロジェクトに取り組み、あなたは働き、すべてがうまくいくようで、プロジェクトが完了する1週間前に彼(顧客)はこう言います。 はい、簡単ではありませんが、YouTubeからです。」 まあ、あなたは何ができますか...何も。
明確にするために、このサイトはAction Script 3.0を使用してFlash CS4で作成されていると言います。
しかし、判明したタスクは簡単ではありませんでした。 そしていつものように外に出なければなりませんでした。
カルマをありがとう! 記事をAdobe Flexブログに移動しました。
開始場所:
関心のあるトピックに関する記事を検索しますか? そして、何が彼らを喜ばせますか、しかし、著者が書いているように、この方法はもはや機能せず、約束された記事の更新はまだ存在しません。 挑戦...
もちろん、プレーヤー全体をダウンロードできますが、Action Script 2で記述されているため、再生の管理を忘れることがあります。 また、ビデオのスケーリングなどの単純なアクションでさえ、耐え難いほど困難なタスクになります。 そして、この方法も消えます。
どうする? 働き、働き、また働きます「そして、あなたはあなたの労苦に報われますように」。 そして、私はステップでソリューションをペイントします:
最初のステップ。 YouTubeプレーヤーをブラウザーキャッシュから取得します(私の場合、FireFoxブラウザーにはabout:キャッシュ機能があります)。
2番目のステップ。 特別なプログラムを使用してプレーヤーのコードを調べます(多くのプログラムがあります。私はSothink SWF Decompilerを使用します)。
第三のステップ。 多数のクラスで必要な情報、つまり、ビデオへの直接リンクを取得する場所と方法を探しています。 この記事から、ビデオへの直接リンクを取得するには、ビデオ識別番号(video_id)と何らかのビデオ識別マーク(パラメーターt)の2つのことを知る必要があることがわかります。 video_idを使用すると、すべてが簡単になります。これは、ビデオのリクエスト行http://www.youtube.com/watch?v=lIZVEnyHoGUにあり、「v」と呼ばれます。 そして、ここに「t」を取得する場所があります。ここで、私たちが分解したプレーヤーが私たちを助けてくれます。そこから、ビデオIDを持つサーバーへの特定のリクエストがあることがわかります。 リクエストは次のとおりですhttp://youtube.com/get_video_info.php?video_id=lIZVEnyHoGU 。 このリンクをブラウザの行に貼り付けると、「get_video_info.php」というファイルをダウンロードするよう求められます。 ファイルの内容をダウンロードして監視します。 ファイルには、「status = ok&vq = None&author = guylevy ...など」という形式の変数を含む行が含まれています。 したがって、私たちが必要とするさまざまな変数のうち、「トークン」と呼ばれるものです。実際、このネットワークは私たちが探していたまさに「t」です。
ステップ4 目的を達成しました-ビデオへの直接リンクを取得し、一緒になったものすべてを追加するとhttp://www.youtube.com/get_video.php?video_id=lIZVEnyHoGU&t= vjVQa1PpcFNnve5gW7h8B51Da_gr8T6BHzSFMbwf6Ww3d%w 「video.flv」という名前のflv-video。これは、プレーヤーでダウンロードまたは再生できます。
したがって、3番目のステップを完了するには、「get_video_info.php」をテキストファイルとしてダウンロードし、そこから必要な情報を取得する必要があります。 フォーラムの1つで見つけた「URL.as」クラスはこれを助けてくれました。URLからほぼすべての情報を取得するのに役立ちます。また、改良後、エンコードされたドット、ダッシュ、プラスなどでURLをエンコードおよびデコードします。 d。
直接リンクを取得するプロセス全体を、クラス「YouTubeVideoPlayer.as」に実装しました
また、クラス「YouTubeVideoPlayer.as」 でYouTubeを操作するための10のトリックに関する記事を使用すると、受信したビデオの品質を設定できます(ある場合)。
実際、「世界を救う」これらの2つのクラス:)
(上記のコードは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)
}
}
}
そして別のクラス
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);
}
}
}
Flex Builderでクラスを使用する例を次に示します。
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script><![CDATA[
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);
}
]]></mx:Script>
<mx:Label x="10" y="12" text=" "/>
<mx:TextInput id="utUrl" x="119" y="10" width="600" text="http://www.youtube.com/watch?v=lIZVEnyHoGU"/>
<mx:Button x="727" y="10" label="" click="GetVideo()"/>
</mx:Application>
この記事が誰かを助けるか、少なくとも面白いと思うことを願っています。
PS
アユルガノフ 、招待ありがとう!