Please consider making a donation if you find this script useful. I find myself providing a lot of free support and maintenance for this code. It would be a great help if I could make a little extra $$ here for my time and effort, and to justify further enhancements to the code. So whaddya say? Help a brother out? Thanks in advance!
!! IMPORTANT NOTICE REGARDING SUPPORT REQUESTS !!
Please read this post before requesting support for either the free or paid-for version of this software!
!! IMPORTANT SOFTWARE VERSION UPDATES !!
As needed, I will periodically post updates here to this code. Each update will be accompanied by an attached ZIP file (with the date of the update as the ZIP file name) that contains the updated files.
3-5-11: An important update to the code is described HERE. You must implement this fix in order to continue using this app without issues! 8-3-11: YouTube changed their FLV URLs again! Get the fix HERE to continue using the app without issues. 12-3-11: YouTube changed the front end of their site again. Get the fix HERE to continue using the app without issues! 12-25-11: I added a download link after successful MP3 conversion, implemented a conversion process progress bar, and refactored some code. Get the latest version of the app HERE. 2-6-12: Improved progress bar so that it reflects download as well as conversion progress, and made significant changes to the code base/structure. Get the latest version of the app HERE. 2-12-12: Fixed various bugs associated with the download/conversion progress bars. Fully adapted code to work on Linux (Ubuntu) as well as XAMPP for Windows. Get the latest version of the app HERE. 7-24-12: Fixed bug that causes the script to crap out when the downloaded YouTube video is corrupt and/or less than 10kb. Some other minor updates, refactoring of code, and bug fixes. Get the latest version of the app HERE. 9-14-12: YouTube changed their video pages' source code, requiring some tweaking of my code to get the video file download links working again. Get the latest version of the app HERE. 10-6-12: Fixed a bug in which errors could possibly occur when two users simultaneously convert the same YouTube video. Get the latest version of the app HERE. 12-6-12: Per recent changes to YouTube's site front end, I fixed the script's ability to determine a given video's title. Get the latest version of the app HERE. 12-19-12: YouTube changed the format of video file URLs in the video page source code. This fix addresses this change. Get the latest version of the app HERE. 3-3-13: Code now accommodates variations in FFmpeg log file formats, which is required for building the conversion progress bar. Get the latest version of the app HERE. 3-21-13: There was a minor change to the format in which the YouTube video URLs are provided. This fix addresses that change. Get the latest version of the app HERE.
If you already have FFmpeg and FFmpeg-PHP installed on your Linux web server (those with sites hosted on shared servers will need to verify this), then you absolutely can run this app on your site. In this case, Linux configuration is identical to Windows configuration with the following exceptions:
1) ffmpeg.exe is no longer required, so you don't need the file on your server. 2) Change the following line of code in config.class.php:
const _FFMPEG = 'ffmpeg.exe';
...to something like...
const _FFMPEG = '/absolute/path/to/ffmpeg';
...depending on where the installation of FFmpeg is located on your server.
Recently, I reeeaally wanted an MP3 audio version of a certain YouTube.com video. I was tired of the online apps that either didn't work or charged you for this service, so I decided to write my own. It was a tad confusing, so I thought I'd share my mini-app with the world to help others who might undertake such an endeavor.
I created the app for my own personal use to run on my Windows development machine using the latest version of XAMPP. I chose this environment for my app because, in this way, I have complete control over server and PHP configurations. And manipulating video and audio files is just plain easier that way. Thus, I suspect that this app won't run in most shared hosting environments (i.e., on a commercial server run by a web hosting company). You'll have to tweak my code in that case...
So, first of all, you will need to download the latest FFmpeg build. I used the Windows 32-bit version. FFmpeg is the software that will ultimately enable you to convert YouTube's FLV video files into MP3 audio files.
Inside the FFmpeg distribution is a /bin/ folder that contains the only file that you'll need: ffmpeg.exe. I have the file in my project/app folder in the web root (htdocs in XAMPP), but you may want to put the file (and other app files/directories) beneath the web root and reference it there (i.e., in a production environment). It's not required for my app to function, but, on a production server, I'm in the habit of putting files there that don't need to be publicly accessible, for extra security. It's your prerogative.
With that in place, you can put both the converter class (YouTubeToMp3Converter.class.php) and example implementation (index.php) into your web root project directory as well. See below for both files:
I'll let you figure out the majority of the code on your own. In a nutshell, the converter class grabs the YouTube FLV url using some regex, downloads the video with cURL, then converts the FLV to MP3 audio by invisibly running FFmpeg in a command shell (with PHP's exec()).
A few things:
1) As I said earlier, the app won't run on commercial servers that have disabled shell access (see use of exec() function in code).
2) The regex to get the FLV urls (and other video information) will undoubtedly break the next time Google drastically overhauls their site....which they did recently....Alternatively, there is probably some API available for grabbing the videos, and maybe one of these days I will integrate that into the code.
3) If you need help with FFmpeg command line flags and general syntax, take a look at the FFmpeg documentation.
4) You will probably want to add some additional data validation/sanitization, as I only coded the minimum required for my needs.
I may update this app periodically if I feel like it. I'm sure it can be improved.
But I am quite sure that this is against YouTube's TOS:
"You agree not to access Content through any technology or means other than the video playback pages of the Service itself, the Embeddable Player, or other explicitly authorized means YouTube may designate."
Good point, and you are certainly correct to bring that up.
I suppose if using some regex to scrape the HTML of YouTube's public pages is a crime, then my script is guilty as charged. (*Trying not to roll my eyes at corporate bureaucracy*)
So the conclusion that I draw here is that, if you use my app in production, on the internet and/or for commercial gain, you'll need to get the explicit written consent/authorization of YouTube first.
In lieu of that, I presume that YouTube authorizes use of it's own API to gain access to its videos repository: http://www.youtube.com/dev. (This is something that I just discovered 5 minutes ago, actually, and substantiates my proposed use of such an API for future versions of my code, as suggested in my original post...)
One can only hope that the large number of sites out there that advertise YouTube video-to-mp3 audio file conversion are using this API. Only YouTube knows for sure, if they even bother to check.
Nevertheless, thanks again for adding this disclaimer regarding use of my app here and for those that similarly endeavor to piggyback YouTube's web services in general.
I took a look at the YouTube API, and, unless I'm missing something, even it doesn't expose a method or property that gives the exact URL of a given YouTube FLV video. The API will give you all kinds of information about a video except for the FLV location. See the following URLs:
Soon after posting my last message on this thread, I realized that the YouTube API does reveal a 3GP file URL for every YouTube video (albeit, presumably inadvertently). 3GP is a mobile device video file extension, for those of you that don't know. It's not FLV, but it is video.
So, with a viable video file source now available to me, I decided to give this video-to-MP3 audio conversion business another stab.
First, you'll need to get yourself a copy of the latest release of the Google Data Client Library, as that will provide you with the core classes required to manipulate the YouTube API. Download the ZIP archive, and unpack the contents to your web server, per the instructions detailed here. I put the files below the web root (for reasons outlined in my initial post of this thread), but let's put it directly in your project folder -- in the web root -- for the sake of simplicity.
Also, for this version of my app, I decided to nix the temporary download of videos in favor of using FFmpeg. I decided to let FFmpeg directly intercept the 3GP video stream and do the MP3 file conversion, all in one easy step. Thus, allowing FFmpeg to shoulder more of the work enables us to no longer need and ultimately delete the 'videos' folder I described in the set up of (for lack of a better name) 'MyApp 1.0' above...
So, again to help you visualize, in XAMPP, my UPDATED final directory structure appears as follows:
You only really need the /library/ directory (as that is where you will tell PHP to look for the API files), but I included the rest of the files for the sake of future reference.
With your new directory structure in place, it's time to look at the new versions of the converter class (YouTubeToMp3Converter.class.php) and example implementation (index.php) (both located in your web root project directory). See below for both files:
Again, I'll mostly let you figure out how the code works. But I will say this:
You'll notice the code is shorter in this version (for you code efficiency purists) and there is no reliance on arbitrary regex patterns scraping the HTML source code to acquire video information. Instead I get my video data via the YouTube API. In fact, the only regex I use is to find the rtsp:// link of the 3GP file located inside a var_export() dump of a Zend_Gdata_YouTube_VideoEntry object (the object that represents all data pertaining to a given YouTube video using the API). Also, I'm no longer using cURL.
A few comments:
1) Seeing how I eliminated the need for a temporary video download directory in this version of my app, you might be wondering if it's possible to do the same for 'MyApp 1.0'. I think it might be possible, but I haven't tried it yet. It would entail grabbing the FLV url generated by YouTubeToMp3Converter::SetFlvUrl and placing that directly into the FFmpeg command executed in YouTubeToMp3Converter::GenerateMP3. The resulting code would look something like the following:
Again, at this time, I don't know if this would work, but it would certainly simplify the code of 'MyApp 1.0'.
2) Obviously, removing the code's reliance on regex to scrape a video page's source code, in favor of acquiring the same data via the YoutTube API, makes my app virtually impervious to future YouTube.com updates and changes. At the very least, use of the API is a generally more reliable and long term solution to converting YouTube videos.
3) And with that said in #2, I have noticed some problems with manipulating the 3GP files exposed by the API:
- It seems that you can save YouTube 3GP files at a bit rate no higher than 160 kbps (using my app). Whether this is a fault of my app, a restriction imposed by YouTube, or a limitation of converting files with the .3gp extension, I cannot say for sure.
- Sometimes conversion of the YouTube supplied 3gp files will fail (using my app) because the rtsp:// links don't work. I'm inclined to think that this is a shortcoming of YouTube, and not some error in my code. In fact, the issue has been documented here, and the problem seems ongoing (as of today's date).
4) As I said earlier, I obtain the rtsp:// link (3GP file link) by digging around inside a dump of the API's Zend_Gdata_YouTube_VideoEntry object. From what I saw, the dump revealed "protected" as well as "public" class members. The 3GP link is a "protected" class value, and is therefore not conventionally exposed by the API. But the value is present in the var_export() dump of the object, and that is why I derive my 3GP file location in this way.
Well, there you have...Yet another way to accomplish the same end...Each way has its pros and its cons; ultimately, you have to decide what is best for you...
Again, I'm sure that any of my code could be improved, and I welcome your suggestions and feedback.
Edit: I completely missed the fact that the API does in fact expose the 3GP file location via conventional means...Ooops!....I'll have to fix that later...Apparently version 2.0 of my app is still a work-in-progress......Stay tuned for further updates to the code!
Edit: I have updated the code to take full advantage of the YouTube API...But I am having a lot of problems converting 3GP to MP3...In addition to faulty 3GP locations exposed by the API (as I noted earlier), it seems that, since 3GP is a mobile device media standard, audio track quality of 3GP files generally isn't the best...I noticed that, in my tests, YouTube's 3GP files are encoded using the AMR or AMR-NB audio codec, which doesn't transcode well to MP3 (libmp3lame in ffmpeg) according to this article, which contains the following excerpt:
"Many modern mobile telephone handsets will allow you to store short recordings in the AMR format, both open source and commercial programs exist (see Software support) to convert between this and other formats such as MP3, although it should be remembered that AMR is a speech format and is unlikely to give ideal results for other audio."
That's enough for me to throw my hands up in the air and quit on this second version of my app....You are more than welcome to try to make the second version work for you, and I'd love to know how you did it, but I'm going to have to settle for 'MyApp 1.0' for now, which still works beautifully, but unfortunately doesn't take advantage of the YouTube API.
It is a free script just using Curl and PHP. It gives three options MP4, 3gp and flv. I want to try and get it to work with mp3, and was wondering if someone can take a look. I think just a little change similar to what you have done before with 3gp conversion could achieve this. I tried myself but I am just learning.
pls am having problem with ur youtube2mp3 app v1. each time i try to use it, i get an error message saying "Error downloading video!". i think am doing everything rite but i still cant get it to work rite. pls i would appreciate any tip u can offer me. thanx in anticipation.
Take a look at the DownloadVideo method in the class. If it returns false, then you get the error message you described. Many things could cause the method to return false.
The first thing I would do is comment out this line:
...to see what PHP errors you are getting, if any.
Also, I would prefer it that you ask your questions within the forum post itself. Chances are that you are not the only person who has had such a problem, so others could benefit from hearing your questions and my responses.
Well I'm currently running this script on the latest version of XAMPP on a Windows 7 Pro 64-bit machine. I've also used it in XAMPP on my older Windows XP Pro 32-bit machine. No problems either way.
You may want to compare your server's configuration to the settings inside XAMPP (Apache and PHP settings). I've only tested this script inside of XAMPP.
I did have to enable the PHP cURL extension in the php.ini for the XAMPP installation, but I don't think that will solve your particular issue here.
Good luck with this. Sorry I can't help more -- but I am unable to reproduce the issue. If you figure out what the problem is, it would be great if you could report back here with a solution. Others with a similar server setup like your own would certainly benefit from it.