YouTube recently changed the way it serves FLV videos and previous methods to get the URL of the FLV files no longer work. As a workaround, it is still possible to retrieve it by:
1. Downloading the YouTube webpage where the video is embedded
2. Parsing it to extract the “t” and “video_id” parameters
3. Building the FLV URL using the old method.
Obviously, having to download and parse the YouTube web page is a lot slower than the previous method, which was just about reading the HTTP headers, but at least it works.
The code snippet below allows to do just that:
public function getFLVURL(iYouTubeVideoURL) {
// iYouTubeVideoURL is the "watch" URL such as:
// http://www.youtube.com/watch?v=OVVvAnU3m6E
var loader:URLLoader = new URLLoader();
var req:URLRequest = new URLRequest(iYouTubeVideoURL);
loader.addEventListener(Event.COMPLETE, this.getFLVURL_complete);
loader.addEventListener(IOErrorEvent.IO_ERROR, this.getFLVURL_ioError);
loader.load(req);
}
private function getFLVURL_complete(iEvent) {
var pageData:String = iEvent.currentTarget.data;
// Get the "t" parameter
var regex:RegExp = /"t": "(.*?)"/;
var result:Array = pageData.match(regex);
if (result.length < 2) {
trace("Error parsing YouTube page: Couldn't get 't' parameter");
return;
}
var param_t = result[1];
// Get the "video_id" parameter
regex = /"video_id": "(.*?)"/;
result = pageData.match(regex);
if (result.length < 2) {
trace("Error parsing YouTube page: Couldn't get 'video_id' parameter");
return;
}
var param_video_id = result[1];
var flvURL:String = constructFLVURL(param_video_id, param_t);
trace("Here's the FLV URL: " + flvURL);
flvTextBox.text = flvURL;
}
private function getFLVURL_ioError(iEvent) {
var loader = iEvent.target;
trace("Couldn't download YouTube web page: " + iEvent);
}
private function constructFLVURL (video_id:String, t:String):String {
var str:String = "http://www.youtube.com/get_video.php?";
str += "video_id=" + video_id;
str += "&t=" + t;
return str;
}
Update (01/12/2008):
As it turns out, this technique only works from Adobe AIR and not from a web page. This is because YouTube doesn’t allow crossdomain calls, which means that if a Flash application tries to fetch one of their pages, it will fail with a security error.
To go around this issue, it is possible to use a simple PHP stub file, which fetches the YouTube page and send it back to Flash. The PHP file would be as follow:
<?php
$url = urldecode($_GET["url"]);
header("Content-Type: text/html");
readfile($url);
?>
Then, in Flash, instead of calling the YouTube URL directly, you call the PHP URL:
var youTubeURL = "http://uk.youtube.com/watch?v=bxfpMGLMZ7Y"
var stubURL = "http://example.com/stub.php?url=" + escape(youTubeURL)
getFLVURL(stubURL);
This small demo illustrates all that. The source code with PHP stub is available here.
Update (19/03/2009):
I’ve posted a follow up to this post with some information on how to get the HD quality version of the videos:
Get the URL of an HD-quality Youtube video.