Youtube video in AS3 FLVPlayback


Lately,
I’ve been busy trying to get youtube movies to play in the standard FLVPlayback component.

Getting this to work was really a pain in the butt now and then, especially because while I was working on this,
youtube changed some stuff on their side undoing all my previous work. But hey, stuff happens!
In the end perseverance and a lot of patience finally resulted in a working solution.

I will break up the solution into several pieces, describing the steps that need to be taken in order for this to work.

1) We need to get the video (.flv) from the youtube server.

To achieve this, one must of course understand how to get this video.
To start off, just navigate to a youtube movie. e.g. http://www.youtube.com/watch?v=vE_WqdKbTvY , then right-click anywhere in page and watch the page source code.

In the source code, search for the string “swfArgs”, which will look something like this:

var swfArgs = {
"q": "top%20gear%20carrera%20gt",
"fexp": "903500,900130",
"invideo": true,
"sourceid": "ys",
"video_id":"vE_WqdKbTvY",
"l": 478,
"fmt_map": "18/512000/9/0/115,34/0/9/0/115,5/0/7/0/0",
"sk": "PbB4AIyvqpbLl0DYyCX5rpmXcQe-FEcZC",
"is_doubleclick_tracked": "1",
"usef": 0,
"t": "vjVQa1PpcFO6TnxVA4_nkqbqKN-z4CoWJgWn2Pfu77I=",
"hl": "en",
"plid": "AARoEenKN8A9FYLn",
"vq": null, "ad_module": "http://s.ytimg.com/yt/swf/ad-vfl91517.swf",
"cr": "NL",
"tk": "j7SixOLxSJ1xxBIwWubnN9sXiu7hrejTmRv4ruMx4N3OaeyhN0xImQ=="};

As you can see this is an object, containing data about the swf and thus the .flv played at the youtube html page.
The video_id is the identifier of the movie and t is a token set by youtube that enables you to view / download the video.
This token expires after a given period of time, so I can’t place a permanent download link for the flv file here.

So now that we have the parameters of the video we need to fill them in as follows into a fixed url, used by youtube to retreive the flv video:

http://www.youtube.com/get_video.php?video_id=[id]&t=[t]

In our case:

http://www.youtube.com/get_video.php?video_id=vE_WqdKbTvY&t=vjVQa1PpcFO6TnxVA4_nkqbqKN-z4CoWJgWn2Pfu77I=

When navigating to this url with your browser, the video will start downloading

Don’t bother trying to open this last link, because as stated before, the token will probably have expired by the time you read this.
(Also the token is linked to the IP that first requested it, which in this case would be mine. More about this later)
If you would like to test if and how this works, just follow all the steps described above and see for yourself.
Pretty cool huh?

Now that we know how to get the .flv video of any youtube movie, we need to find a way to automatically do this, without the need to go through all the steps again.
We will use a php proxy script that eliminates all sandbox issues, accepts any youtube url and then returns the physical video (.flv) as if it were present on our own server.
However, this script will be a mere redirect to the location of the video on youtube servers, the file will not be physically downloaded by your server.

To create a script like this, I did some searching and quickly stumbled upon a script I found here.
This worked fine at first, but as I was saying youtube changed some things server side along the way.
That’s why i needed to search for a solution and needed to modify the script in order to getting it to work again.

The problem was caused because youtube changed the token idea.
A token is now linked to an IP address, meaning that the video can only be downloaded by the IP address that first requested the token.
This is a problem when trying to do this in-browser, where the browser is on the localhost, and the script is on a server and thus causing an IP mismatch. The result is that the file cannot be accessed.
After alot of searching around the final solution is to retreive the headers from the youtube download url and extracting the location of the flv that is embedded.

The result for the php proxy script:

<?php
    $id = trim($_REQUEST['id']);

    $url = "http://www.youtube.com/watch?v=" . $id;

    $url = $url . "&fmt=18"; //Gets the movie in High Quality, uncomment this line to get it in normal quality

    $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('#var swfArgs = (\{.*?\})#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 all 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
?>

An example of correct usage:

Navigate to http://www.dennisjaamann.com/demo/youtubeFLVPlayback/php/getYoutubeFLV.php?id=[videoID],
where the videoID is the id from the youtube movie http://www.youtube.com/watch?v=vE_WqdKbTvY
In this case: http://www.dennisjaamann.com/demo/youtubeFLVPlayback/php/getYoutubeFLV.php?id=vE_WqdKbTvY
When navigating to the url above, you will notice that the script will redirect you to the physical location of the .flv file.This will start the download prompt.

Isn’t this exactly what we need? :)

2) Workaround for FLVPlayback

When we take the url retreived above and try to play it in the standard FLVPlayback component as follows:

var videoPlayer:FLVPlayback = new FLVPlayback();
addChild(videoPlayer);
videoPlayer.source = "http://www.dennisjaamann.com/demo/youtubeFLVPlayback/php/getYoutubeFLV.php?id=vE_WqdKbTvY";
videoPlayer.play();

The video doesn’t play and we get the following error:
VideoError: 1005: Invalid xml: URL: “http://www.dennisjaamann.com/demo/youtubeFLVPlayback/php/getYoutubeFLV.php?id=vE_WqdKbTvY&FLVPlaybackVersion=2.1″ No root node found; if url is for an flv it must have .flv extension and take no parameters
at fl.video::SMILManager/http://www.adobe.com/2007/flash/flvplayback/internal::xmlLoadEventHandler()
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at flash.net::URLLoader/onComplete()

Which is kind of a suprise, because when we open the source url in our browser there is clearly an .flv file there.

However, when analyzing the error message we can clearly see the problem. The key part here is:
“if url is for an flv it must have .flv extension and take no parameters”
When taking a look at our url http://www.dennisjaamann.com/demo/youtubeFLVPlayback/php/getYoutubeFLV.php?id=vE_WqdKbTvY,
it is obvious that it doesn’t end on .flv and that our url accepts parameters.

This behaviour is caused by a few lines of code in the NCManager class used by the FLVPlayback component.
There, the check is done whether the url ends on .flv and that the url does not accept parameters.

This leaves us 2 options:
- Extend the NCManager, overwrite this behaviour and make the FLVPlayback use this custom class
- Find a way to give the NCManager a correctly formatted url, so that it can stop nagging

I prefer the second option because it leaves the NCManager unmodified and hereby we can eliminate any unwanted behaviour.
Also, since I have a little php experience, I quickly realized that this had the funky smell of url rewriting.
With url rewriting you can take any url and format it to the format required which is exactly what we need here…

So we need to change the original url
http://www.dennisjaamann.com/demo/youtubeFLVPlayback/php/getYoutubeFLV.php?id=vE_WqdKbTvY
to

http://www.dennisjaamann.com/demo/youtubeFLVPlayback/videos/vE_WqdKbTvY.flv

This can be achieved by adding a .htaccess file to your project folder on the web server.
The code below is also included in the source files at the bottom of this post. But please note, not all operating systems show a .htaccess file.
This is because that it sometimes is a hidden file type.

Here’s the code for that:

Options +FollowSymlinks
RewriteEngine on
RewriteRule ^videos/([^/]+).flv php/getYoutubeFLV.php?id=$1 [NC]

And that’s all folks!
When we now execute our code again with the modified url, the NCManager has stopped nagging and the videoplayer plays the wanted video.

var videoPlayer:FLVPlayback = new FLVPlayback();
addChild(videoPlayer);
videoPlayer.source = "http://www.dennisjaamann.com/demo/youtubeFLVPlayback/videos/vE_WqdKbTvY.flv";
videoPlayer.play();

This workaround took like a minute or so to be succesful, leaves the the NCManager unchanged and does the trick.
That’s why I’ve chosen this solution because it is simple and elegant.

Read more about basic url rewriting here

3) Create the player.

All that is left now is to create our application. I have prepared an example in flex (sdk 3.3)

This is the result:

View the full example with source here
Or download the example source files here: youtubeFLVPlayback (2977)

, , , , ,

  1. #1 by Pablo on April 27, 2009 - 7:50 pm

    Ole ole y ole (Spanish phrase, sorry for my english)

    Thank you very much!!!! You are my heroe!!!! (I am crying from emotion)

    I spent 2 months trying hard to embed videos from youtube in flex (youtube api, youtubebridge, youtubewrapper, tubeloc, toobplayer…) and i hate flex for this.

    I knew that in substance the flvPlayback could play youtube videos but did not know how to convert an address. Flv

    If you ever come to Spain, you are invited to what you want!

    Thanks again campeon!

  2. #2 by Dennis on April 28, 2009 - 11:22 am

    @Pablo
    Hi pablo,

    Great I could help

    However I would strongly advise you not to use this method in any commercial project, because it might be considered as a “hack” by youtube and collide with their terms of usage.

    I don’t think this problem can occur when using tubeloc. It uses youtube’s very own chromeless video player and thereby it may not be considered as “illegal terms of use”.
    I tried it out and it works perfect!
    A limiting factor could be that you want to display multiple videos at a time…

  3. #3 by Pablo on April 28, 2009 - 4:08 pm

    Hi dennis!

    My web page is a non commercial project.

    I know that get the url is not “legal” but I just only use this way to show videos. In my oppinion the ilegal thing is use it to download videos.

    As you say, tubeloc is fine but I need to show multiple videos in one application.

    Thanks again!

  4. #4 by Paul on April 30, 2009 - 6:08 pm

    Hi Dennis,

    Great work – very impressive.

    There is something that caught my eye though (and sorry that this is a bit of a tangential issue) to do with the full screen functionality.

    I am using the standard FLVPlayback component with a standard skin. The problem is that when I click the full screen button, the “Press Esc to exit full screen mode” message is stretched and pixelated, also the controls for the playback component become huge!

    You seem to be using the standard flash component with a standard skin as well but you don’t seem to have this issue. Could you tell me please if you did anything special for this to be the case?

    I am using Flash CS4 (AS3), the FLVPlayback component, the SkinUnderPlayStopSeekFullVol.swf skin and the scaleMode is set to “maintainAspectRatio” (although I have tried all the options for this).

    Thanks very much.

    Paul

  5. #5 by Dennis on April 30, 2009 - 7:51 pm

    @Paul

    Hi Paul,

    I noticed that too when I was creating this example.

    It’s all in one magic line of code :)

    videoPlayer = new FLVPlayback();
    videoPlayer.width = videoContainer.width;
    videoPlayer.height = videoContainer.height;
    videoPlayer.skinAutoHide = true;
    videoPlayer.skin = "http://www.dennisjaamann.com/demo/youtubeFLVPlayback/assets/SkinOverAllNoCaption.swf"
    videoPlayer.skinScaleMaximum = 1; //Setting the skinScaleMaximum property to one solves your issue Paul
    videoPlayer.getVideoPlayer(videoPlayer.activeVideoPlayerIndex).smoothing = true; // smooth the video
    videoPlayer.skinBackgroundColor = 0xFFFFFF;
    videoContainer.addChild(videoPlayer);
    

    And that’s it… Easy huh?

    It’s all in the source files of the sample I created, so feel free to download it.

    Grtz

  6. #6 by Paul on May 1, 2009 - 9:47 am

    Hi Dennis,

    Thank you so much for that.

    I had actually seen that property in the API but it said it was “Only available in the AIR runtime” so I didn’t even try it! That’ll teach me…

    Thanks again – I really appreciate it…such a swift response and exactly the answer I was looking for as well.

    Cheers

    Paul

  7. #7 by milan on May 8, 2009 - 10:38 am

    thanks dennis! you’re the man!

  8. #8 by Michael on May 13, 2009 - 6:15 am

    This code doesnt grab the HQ video even with the fmt=18 in the url. Is there another way?

    • #9 by Dennis on May 13, 2009 - 8:55 am

      Actually it does.

      For the test I have taken
      http://www.youtube.com/watch?v=WaWoo82zNUA

      And added the parameter
      http://www.youtube.com/watch?v=WaWoo82zNUA&fmt=18

      As you can see the video is in HQ. This is also the video retreived.
      But…
      Some youtube video’s DO NOT have a HQ version.

      And there’s more… actually fmt=18 is medium quality for youtube videos.
      This quality setting retreives a video in .flv format.

      The highest quality can be retreived by adding fmt=22 to the url.
      This will retreive a video in MP4 format.

      But as stated before, not all videos have these higher quality videos available…

      Regards

  9. #10 by Josh Reid on May 27, 2009 - 4:34 am

    ABSOLUTE LEGEND – Thank you this post has saved me a huge headache ;)

  10. #11 by lukegill on June 3, 2009 - 2:04 pm

    Really grateful for this post!
    I’ve been looking all over for this and your the only post that actually works…genius!

  11. #12 by Ne0 on June 13, 2009 - 1:07 pm

    excellent workaround, thanks for sharing!!!

  12. #13 by Vipin on June 23, 2009 - 1:07 pm

    One word….Awesome…. :)
    I was searching and investigating long for this solution; I was getting all sorts of Security Sandbox Exceptions while trying to stream, but after seeing your post, it made my life simpler…

    Thanks again for sharing the code…

    :-)
    Vipin

  13. #14 by Vipin on June 23, 2009 - 2:47 pm

    Hey Dennis,
    Just one question…I have got the YouTube URL (the t variable and other things) using a flash desktop application (not a web based one). How can I stream this gotten URL in my desktop application? (I can’t put the PHP code because there is no server involved!!! )

    Replies appreciated…

    -Vipin

    • #15 by Dennis on June 23, 2009 - 3:03 pm

      Hi Vipin,

      From your words I can derive that you have probably made an url request to retreive the t variable.

      The next thing to do would then be to construct the full path to get the video from.
      The only problem is that you would have to do the request to the full path and then be able to read the headers like in the php script.
      The code below gets some params from the headers.

      $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 all 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;
      	}
          }
      

      By navigating to the header item that contains location, you might be able to get the video..
      But maybe then you will need a proxy because of sandbox violations (except in AIR).

      I currently cannot think of any way to read urlrequest headers in AS3…

      I have been looking for this solution too and it is in my to do list, but i’m afraid that at this moment I cannot help you with that (very busy at boulevart).

      If you would find a solution, please let me know.

      Regards

  14. #16 by rudi on July 13, 2009 - 12:59 pm

    for solve the .htaccess problem I use this system:
    package mpc.cairngorm.news.view{
    import flash.display.Sprite;
    import flash.events.*;
    import flash.media.Video;
    import flash.net.NetConnection;
    import flash.net.NetStream;

    import mx.core.UIComponent;

    public class MyVideo extends UIComponent
    {
    private var videoURL:String = “http://www.yoursite.com/video/getYouTubeFLV.php?id=idvideo”;
    private var connection:NetConnection;
    private var stream:NetStream;

    public function MyVideo() {
    connection = new NetConnection();
    connection.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
    connection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
    connection.connect(null);
    }

    private function netStatusHandler(event:NetStatusEvent):void {
    switch (event.info.code) {
    case “NetConnection.Connect.Success”:
    connectStream();
    break;
    case “NetStream.Play.StreamNotFound”:
    trace(“Unable to locate video: ” + videoURL);
    break;
    }
    }

    private function connectStream():void {
    stream = new NetStream(connection);
    stream.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
    stream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);
    stream.client=new CustomClient();
    var video:Video = new Video();
    video.attachNetStream(stream);
    stream.play(videoURL);
    addChild(video);

    }

    private function securityErrorHandler(event:SecurityErrorEvent):void {
    trace(“securityErrorHandler: ” + event);
    }

    private function asyncErrorHandler(event:AsyncErrorEvent):void {
    // ignore AsyncErrorEvent events.
    }

    public function onMetaData(info:Object):void {
    trace(“metadata: duration=” + info.duration + ” width=” + info.width + ” height=” + info.height + ” framerate=” + info.framerate);
    }

    }
    }
    class CustomClient {
    public function onMetaData(info:Object):void {
    trace(“metadata: duration=” + info.duration + ” width=” + info.width + ” height=” + info.height + ” framerate=” + info.framerate);
    }
    public function onCuePoint(info:Object):void {
    trace(“cuepoint: time=” + info.time + ” name=” + info.name + ” type=” + info.type);
    }
    }

    • #17 by Dennis on July 14, 2009 - 9:29 am

      Hi Rudi,

      Nice solution.

      I see that you are using a video component instead of an flvplayback.
      This is an option indeed to not use the .htaccess.

      I preferred to device a solution within an flvplayback because it has some standard behaviour that I liked (fullscreen, cuepoints, …)

      Thanks for you input,

      Regards

  15. #18 by greghudd on July 13, 2009 - 8:23 pm

    Hi (Thanks for this very inventive method!)

    Wonder if this method would work to get to Red5 server content via the flex video component…?
    Has anyone tried this yet?

    From my perspective, this seems to be the largest barrier against using the open source red5 serving solution going fwd.

    Cheers GH

  16. #19 by Dennis on July 14, 2009 - 9:54 am

    @ greghudd

    Hi greg,

    Why would you use this method on a red5 server?

    The first option is that it has built in video / audio streaming capabilities using rtmp.
    Flvplayback can handle an rtmp stream out of the box.
    You could easily mimic the behaviour of the php script to retreive youtube videos and then stream them through.

    A second possibility could be to use the Red5 built in AMF gateway to serve as your proxy to retreive videos from.
    This way you could retreive videos with an RPC call.

    These are just some first thoughts.

    Regards

  17. #20 by Josh Noble on September 3, 2009 - 3:31 pm

    I’m trying to working this into a project (http://www.visualdialects.co.uk/lastfm) I’ve got going at the moment and this post has been super useful. Thanks for sharing.

  18. #21 by Nelson on September 23, 2009 - 7:54 pm

    hi i need help i want put a video from vimeo.com
    can you help?

    thanks

    var videoPlayer:FLVPlayback = new FLVPlayback();
    addChild(videoPlayer);
    videoPlayer.source = “http://vimeo.com/5393611″;
    videoPlayer.play();

  19. #22 by Dennis on September 23, 2009 - 8:14 pm

    @Nelson
    Hi Nelson,

    I’m afraid it’s not as simple as the source code you put above here.

    First of all, you will probably need a proxy to load content from a site where your .swf is not hosted (crossdomain issue)

    Second, after a quick glance at the source code of vimeo.com, I noticed that the video is retreived from an swf file as follows:

    http://vimeo.com/moogaloop.swf?clip_id=5393611

    This means that swf on vimeo.com accepts a parameter identifing the movie and then retreives it from the server in that swf.
    This also means that there really is no telling how or where the video file is located to show it in your own media player.

    However you could just load the swf with that parameter into your application (also showing the vimeo.com player).

       
    

    A little something like this.

    If this doesn’t do for you and you really want the flv video, you will need to decompile the swf and look for clues there on how the video is retreived from the server.

    Hope this helps,

    Regards

  20. #23 by Olivier on October 1, 2009 - 5:20 pm

    Hi Dennis,
    just read your post and find it quite interesting, but unfortunately doesn’t exactly answer my problem. I’ve looked around the web and your post is the closest solution, but I’d need some quick help if you don’t mind.

    Basically, what I want to know is how to use “solution 1″, which is Extending NCManager to override the .flv extension and stuff. I’ve looked into NCManager but couldn’t find my way.

    I don’t have access to the server thus I can’t edit the .htaccess file. Plus, we have our own webapp that delivers files through a uuid. So I need to use as source something like that: asset.do?uuid=98ba4c90-d428-48f8-8a7e-8038133fae49′(backend in Java)

    The file pushed throught the service is the .flv but as you can expect I’m getting the 1005 error…

    Think you can help?
    you can contact me through email too (not sure if you have access to it?)

    • #24 by Dennis on October 2, 2009 - 9:34 am

      Hi olivier,

      I found a post about how to extend the NCManager to do exactly that.
      It seems that it is enough to override the connectToURL() method.

      This is the url (in dutch) but the code speaks for itself.
      http://www.flashfocus.nl/forum/showthread.php?t=43737

      Hope this helps,

      Regards

  21. #25 by Olivier on October 2, 2009 - 2:25 pm

    Thanks Dennis, I’ll take a look into it

    It’s greatly appreciated.
    I’m also wondering why Adobe (or mx) did choose this method (check extension of the url) to tell apart an FLV from a SMIL file… That’s kind of limiting in a really bad way and I don’t this don’t conform to good practices… Anyways, thanks for the link!

    O.

  22. #26 by Dennis on October 2, 2009 - 2:36 pm

    @Olivier
    Olivier,

    Looking at the way the flvplayback component is built, it is clear that its main purpose is to work well with streamed video.

    My guess is that they(adobe) do that to promote their adobe media server solution for streaming video to high profile clients.
    From a commercial point of view that’s genious!

    This is indeed not good practice. However their code is open source and open for modification, making it do-able for medium to high experienced developers to code their own implementation.

    This said and done, making your own implementation will probably cost more to a firm than just using the adobe media server solution (or opensource red 5).

    This is just my opinion though.

    Regards,

    Dennis

  23. #27 by Rajesh on October 5, 2009 - 2:36 pm

    Hi Dennis,

    I have created a Flash Desktop player, intended to stream videos from youtube. I tried your method, and I got the video_id and the ‘t’ variable, but problem is when I try to give the URL to my desktop Flash player as:

    flvplayback.source = “http://www.youtube.com/get_video.php?video_id=vE_WqdKbTvY&t=vjVQa1PpcFO6TnxVA4_nkqbqKN-z4CoWJgWn2Pfu77I=”;
    flvplayback.play();

    : it either throws Security Sandbox Exceptions or the video will not get played.

    I don’t have access to any server, (since this is not a web based application). I want to run the youtube video locally on my Flash desktop application.

    Please try to provide a soluton for my problem. And thanks in Advance.

    -Rajesh

    • #28 by Dennis on October 5, 2009 - 2:49 pm

      Hi Rajesh,

      The security sandbox error is thrown because youtube has a crossdomain.xml that restricts acces to limited domains and servers that can acces their videos.
      The way to get around this is by using a proxy (the php script to catch the video) to trick flash into thinking the data is actually retreived from that script.

      This script is available for you in the attachment that comes with this post.

      Since you are running it locally, you will have to be inventive though.
      You will still need another programming language to do the “catching” of the video for you.

      You could try to set up something like xammp to run my php script on your localhost if this application doesn’t need to be distributed.

      Otherwise, if your application DOES need to be distributed to other environments, the best way to go here (working on your local pc) is probably java.
      You could set up a bridge using Merapi. This lets flash and java communicate.
      Your java should then catch the video in the exact same manner as in the php script and send it to your flash application.

      You could then make a java installer for distribution that installs the java bridge and your flash (air application).

      Hope this helps,

      Regards

  24. #29 by Rajesh on October 5, 2009 - 2:38 pm

    And also in your URL, http://www.dennisjaamann.com/demo/youtubeFLVPlayback/videos/vE_WqdKbTvY.flv when it is put in a browser, it downloads the file as video.flv. What is the PHP script doing on your server and How is this FLV getting downloaded? Are you running any other script besides the script to get the video_id and the t variable?

    -Rajesh

  25. #30 by Rajesh on October 6, 2009 - 7:41 am

    @Dennis
    Thanks Dennis for the quick Reply. What I am doing now for my Desktop Flash app is, “catching” the FLV file using a C#.NET application, and then sending a message back (containing the local download location) to Flash for it to play.

    Most of the time (say 90%) this works. Problem happens when some times the file won’t play due to negligible file size download. It’s a UI application, in which if a user clicks on a thumbnail, the video starts streaming and if he clicks on another thumbnail, this other video will start streaming. Most of the times, when the user clicks on the second thumbnail, it just shows up a blank screen since the size of the file downloaded won’t be enough for Flash to play. This is a bad user experience!

    Any ideas on this?

    -Rajesh

  26. #31 by Olivier on October 6, 2009 - 2:36 pm

    @Rajesh
    If I understand correctly you could try this:

    1 – user click videoA and starts streaming
    2 – user click videoB
    3 – VideoA continues playing *while* videoB is buffering (show a loading anim or something)
    4 – As soon as videoB has enough buffer fade both videos in and out to transition to videoB

    Just my 2¢

  27. #32 by Elferne on October 22, 2009 - 3:26 am

    Did youTube changed the video args? Yesterday, the script was working fine. But today when I tried to run the script, it gave me the next message “Couldnt detect swfArgs”. I don’t know if I’m doing something wrong or if youTube video args has been changed. Please I need help with this.

    PD: sorry for my english.

    • #33 by Dennis on October 22, 2009 - 8:59 am

      Hi elferne,

      Apparently they did…
      And after taking a quick peek in the new version, there is no apparent way to get the video url from…

      To get this working again, monitoring request etc will be necessary all over again. With no guarantee of results of course.

      Regards

  28. #34 by Swami Charan on October 22, 2009 - 10:44 am

    Hi Dennis,

    I was checking the PHP script you provided here for getting Youtube FLV Path. It was working fine previously, but it stopped returning the $t variable.

    Could you please let us know how to make it work?

    Thanks
    Swami

    • #35 by Dennis on October 22, 2009 - 10:49 am

      Hi Swami,

      It appears that youtube changed the way it retreives videos from the server.

      So the method using the t variable no longer works.

      I will take a look into it when I have the time, but I have to figure out a whole new method of retreiving the video.

      Regards

  29. #36 by cmoore on October 22, 2009 - 3:09 pm

    Hey guys I’ve been working on trying to figure out youtube’s new schema let me know if you wanna join in the fight (naturalui at gmail.com)

    Here are my notes so far http://nuiman.com/youtube_notes.txt

    I’ll keep you posted on my efforts of parsing the proper variables out… still using CURL but running into some problems targeting the JSON.

    Lets see how fast we can get it back :)

  30. #37 by Dennis on October 22, 2009 - 3:12 pm

    @ cmoore

    Hi, I already solved the problem today and its described in a new post in this blog.

    Regards,

    Dennis

  31. #38 by cmoore on October 22, 2009 - 3:23 pm

    Your awesome Dennis thanks 10x :)

  32. #39 by Elferne on October 22, 2009 - 10:58 pm

    @Dennis

    Dennis u ‘re god!! Thank u very much!!!

    Cheers from Argentina!

  33. #40 by Elferne on October 23, 2009 - 2:26 am

    Damn youTube!! It changed the way that it retreives videos from the server… again!!

    In the php proxy script change the line 16:
    (if (!preg_match(‘#CFG_SWF_ARGS: (\{.*?\})#is’, $info, $matches)))

    to:
    if (!preg_match(‘#’ . $swfVar . ‘ (\{.*?\})#is’, $info, $matches))

    Thanks again Dennis!

  34. #41 by Elferne on October 23, 2009 - 2:30 am

    Sorry, but i don’t put the string value for $swfVar :P

    $swfVar = ‘\’SWF_ARGS\’:';

    so.. the line 16 is:

    if (!preg_match(‘#\’SWF_ARGS\’: (\{.*?\})#is’, $info, $matches))

  35. #42 by klinQ on October 23, 2009 - 12:45 pm

    @Elferne
    Hey i’ve got
    Warning: Unexpected character in input: ‘\’ (ASCII=92) state=1 in …

    when I use
    $swfVar = ‘\’SWF_ARGS\’:’;

    How to fix it?

  36. #43 by klinQ on October 23, 2009 - 1:27 pm

    How should this line look like now?

    if (!preg_match(’#\’SWF_ARGS\’: (\{.*?\})#is’, $info, $matches))

    didnt work

  37. #44 by ElFerne on October 23, 2009 - 4:33 pm

    @klinQ

    that is a problem with the quotation mark when I paste into the post

    you have to change the quotation mark from ´ to ‘

    $swfVar = ‘\’SWF_ARGS\’:';

  38. #45 by klinQ on October 25, 2009 - 1:51 pm

    Could u send me phpfile ?
    I tried many different ways and still got no working script :( klinick@scholaris.pl big thx & sorry my eng.

  39. #46 by Dennis on October 25, 2009 - 1:57 pm

    @klinQ
    Hi klinQ,

    You can find the source code of the new and improved php on the homepage of my blog, in the new post about the youtube update.

    Or, you can download the sources of this post again, the improved php file is included there.

    Regards,

    Dennis

  40. #47 by klinQ on October 26, 2009 - 5:49 pm

    Another problem:

    Warning: get_headers() [function.get-headers]: URL file-access is disabled in the server configuration in /home/klinick/public_html/YTRadio/php/getYoutubeFLV.php on line 39

    Warning: get_headers() [function.get-headers]: This function may only be used against URLs. in /home/klinick/public_html/YTRadio/php/getYoutubeFLV.php on line 39

    Warning: Invalid argument supplied for foreach() in /home/klinick/public_html/YTRadio/php/getYoutubeFLV.php on line 41

    How to make it work without get_headers()?

  41. #48 by enricoB on January 2, 2010 - 12:05 am

    thanks a lot for the .htaccess solution!
    i finished to implemented a youtube as3 videoplayer!

  42. #49 by Anon on March 24, 2010 - 6:14 pm

    Anyone have a copy of this working? I have tried a bunch of different curl options and ways of getting the videos but now it seems youtube has added a layer to block outside requests. It adds some new variables to the FLV request and changes the IP for example 200.0.0.0 (blocked) but works fine when its 0.0.0.0 – note in the page sources twice.

    Would love to get this back working its really a smooth way to watch youtube vids.

  43. #50 by Ben on April 16, 2010 - 1:34 am

    In lieu of the ability to edit the .htaccess file a much simpler solution is available to those who have written their own streaming/pseudo-streaming script.

    The AS2.0 FLVPlayback object will accept the following url:
    video.php?id=blah&format=.flv

    Not sure if this is true of later versions, but at least the one I’m using appears to merely check for the url ending of “.flv”, which is satisfied by this trailing parameter.

(will not be published)


  1. Luke Gill - Web Design Belfast, Northern Ireland» Luke Gill - Web Design Belfast, Northern Ireland
  2. OddlyStudios » Blog Archive » Youtube Notes - Part One
  3. LastFM/Amazon/Youtube Mashup | VISUAL DIALECTS