Youtube video in AS3 FLVPlayback Update(2)

After the update of yesterday,

Youtube changed the way on how to retreive the video from it’s html page again.
This implies, that the 2 old versions of the proxy no longer worked and that videos could no longer be retreived.

After a quick peek, the solution was rather simple.
Here’s the code for the new and improved proxy:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?php
    $id = trim($_REQUEST['id']);
 
    $url = "http://www.youtube.com/watch?v=" . $id . "&fmt=18";
 
    $ch = curl_init();
 
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
 
    $info = curl_exec($ch);
 
    if (!preg_match('#\'SWF_ARGS\': (\{.*?\})#is', $info, $matches))
    {
        echo "Check the YouTube URL : {$url} <br/>\n";
        die("Couldnt detect swfArgs");
    }
 
    if (function_exists(json_decode)) # >= PHP 5.2.0
    {
	$swfArgs = json_decode($matches[1]);
        $video_id = $swfArgs->video_id;
        $t = $swfArgs->t;
    }
    else
	{
        preg_match('#"video_id":.*?"(.*?)"#is', $matches[1], $submatches);
        $video_id = $submatches[1];
 
        preg_match('#"t":.*?"(.*?)"#is', $matches[1], $submatches);
        $t = $submatches[1];
    }
 
	curl_close($ch);
 
	$fullPath = "http://www.youtube.com/get_video.php?video_id=" . $video_id . "&t=" . $t; // construct the path to retreive the video from
 
	$headers = get_headers($fullPath); // get al headers from the url
 
	foreach($headers as $header){ //search the headers for the location url of youtube video
		if(preg_match("/Location:/i",$header)){
			$location = $header;			  
		}
	}
 
	header($location); // go to the location specified in the header and get the video
?>

That’s all there is to it.

This file will also be updated again in the source and files download of the original post.

Tags: , , , , ,

  1. #1 by Swami Charan on October 23rd, 2009 - 2:46 pm

    Dennis,

    thanks for your help in fixing this…Its working now.

    I have one query, when i tried to get the video using “&fmt=18″ parameter, its still not loading HD video.

    Could you please help me in getting path to Youtube HD video?

    Thanks
    Swami

    RE Q
  2. #2 by GhostD on October 23rd, 2009 - 4:58 pm

    @Swami Charan
    This code always retreives the lowest quality video header available. If you want to retrieve the HQ header you must add . “&fmt=18″ to line 37:

    $fullPath = “http://www.youtube.com/get_video.php?video_id=” . $video_id . “&t=” . $t . “&fmt=18″;

    If you want a HD header assuming there’s one available you’ll need to add “&fmt=22″ instead. Although in that case you may need to change line 4 to “&fmt=22″ as well.

    RE Q
  3. #3 by cmoore on November 1st, 2009 - 6:31 am

    Anyone having issues with the current parsing? It seems they changed once again?

    RE Q
  4. #4 by Swami Charan on December 8th, 2009 - 7:59 am

    Hi Dennis,

    Until couple of days back, i could able to get HD Videos from youtube with this script by appening “&fmt=22″ in both line 4 and 37.

    When i try to play a HD video today, its not returning the T var for HD Stream.

    It shows following output on executing the script to get HD Stream:

    Check the YouTube URL : http://www.youtube.com/watch?v=cEmxxLlsTRE&fmt=22
    Couldnt detect swfArgs

    Could you please help me out in getting HD Video from youtube?

    Thanks
    Swami

    RE Q
  5. #5 by w0rse on December 10th, 2009 - 6:36 pm

    Here’s the one working for me at the moment:

    if (!preg_match(’#\’SWF_ARGS\’: (\{.*?\})#is’, $info, $matches))
    {
    echo “Check the YouTube URL : {$url} \n”;
    die(”Couldnt detect swfArgs”);
    }

    $swfArgs = json_decode($matches[1]);
    $url_map = explode(’|', urldecode($swfArgs->fmt_url_map));

    curl_close($ch);

    //it looks like:
    // $url_map[1] – hd quality mp4
    // $url_map[2] – hi quality flv
    // $url_map[3] – mid quality flv
    // $url_map[4] – low quality flv

    $fullPath = explode(’,', $url_map[$quality]); //strip a strange nuber that goes after comma

    header(”Location:”.$fullPath[0]);

    Thank you, Dennis, for your original research.

    RE Q
  6. #6 by Philip Bulley on January 12th, 2010 - 10:56 am

    For any newbies reading this, I think you should point out that this is not the best way of playing youtube videos via Flash. Scraping youtube pages will cause your site to go down every time youtube changes the structure of their pages, and is against YouTube’s terms of service.

    Developers should use the official YouTube chromeless player @ http://code.google.com/apis/youtube/chromeless_player_reference.html, which the guys at YouTube fully support. FYI, you can even create all your own play controls with this player and ditch the ugly standard YouTube buttons.

    But of course, you’re old enough to make your own decisions :)

    RE Q
  7. #7 by zago on March 20th, 2010 - 8:20 pm

    there have another change in YT … can u research again ?

    RE Q
  8. #8 by Anon on March 24th, 2010 - 9:03 pm

    Anyone have this script working? Awesome job by the way Dennis!

    RE Q
  9. #9 by dude on April 6th, 2010 - 4:08 pm

    Is it my imagination or is even the updated script no longer working? ie youtube have changed the flv urls? If anyone figures it out – I’d be most grateful if you could post it here, as I hope to :)

    RE Q

SetPageWidth