flagbug / YoutubeExtractor

A .NET library, that allows to download videos from YouTube and/or extract their audio track (currently only for flash videos).
813 stars 374 forks source link

Download Video With Audio #78

Closed mysteryx93 closed 10 years ago

mysteryx93 commented 10 years ago

There are 2 issues when downloading HD videos

First, it takes 30 seconds to pull out the data of a HD video such as https://www.youtube.com/watch?v=fYP_3QEb5Yk

For a SD video such as this one, it takes only 15 seconds https://www.youtube.com/watch?v=uzSPCac116E

Since it falls flat on 15 sec and 30 sec, that might be a timeout issue.

Second problem is that there is no way to download a HD video with audio! For the first HD video, I displayed the list of video formats, bitrates and audio formats. How can I download a 1080p video with audio? Not possible...

.mp4 720 .aac .webm 360 .ogg .mp4 360 .aac .flv 240 .mp3 .3gp 240 .aac .3gp 144 .aac .mp4 1080 .webm 1080 .mp4 720 .webm 720 .mp4 480 .webm 480 0 0 .mp4 360 .webm 360 .mp4 240 .webm 240 .mp4 144 .mp4 0 .aac .webm 0 .ogg

flagbug commented 10 years ago

Second problem is that there is no way to download a HD video with audio! For the first HD video, I displayed the list of video formats, bitrates and audio formats. How can I download a 1080p video with audio? Not possible...

YouTube only provides separate video and audio channels for HD videos, it's called DASH playback and you'll have to merge the video and audio manually.

mysteryx93 commented 10 years ago
  1. How do I go about downloading the 1080p video's HD audio?
  2. Couldn't the library merge the audio and video together? That needs to be done anyway. If not by this library, it has to be custom-coded by anyone using it. There are several utilities out there that allow proper downloading of HD videos. Not sure how they handle this.
flagbug commented 10 years ago

How do I go about downloading the 1080p video's HD audio?

Look at the AdaptiveType property.

Couldn't the library merge the audio and video together? That needs to be done anyway. If not by this library, it has to be custom-coded by anyone using it. There are several utilities out there that allow proper downloading of HD videos. Not sure how they handle this.

Use FFmpeg for this

mysteryx93 commented 10 years ago

Ah ok, those with 0 resolution were the audios.

  1. Why are there delays of 15 or 30 seconds to pull out the info of some videos?
  2. Wouldn't it be a good idea to have a wrapper class within the library that downloads both the audio and video and merges them together with FFmpeg? That probably would be an additional class that would use the current download functions. If not, then anyone using the library to download HD videos needs to custom-code such a class.
flagbug commented 10 years ago

Why are there delays of 15 or 30 seconds to pull out the info of some videos?

No idea, works nearly instantly for me

Wouldn't it be a good idea to have a wrapper class within the library that downloads both the audio and video and merges them together with FFmpeg? That probably would be an additional class that would use the current download functions. If not, then anyone using the library to download HD videos needs to custom-code such a class.

I really don't want to maintain a FFmpeg wrapper, in fact I don't even want the audio and video downloader classes, but I'll keep them so people don't whine if I remove them.

mysteryx93 commented 10 years ago

Ok, serching ffmpeg, dash and muxing allowed me to find the information I need. This is the command to merge both files. ffmpeg -i audio.mp3 -i video.avi -acodec copy -vcodec copy output.avi

Now, for the freeze, this is strange. I run this command (I'm currently in Mexico) var L = YoutubeExtractor.DownloadUrlResolver.GetDownloadUrls("https://www.youtube.com/watch?v=fYP_3QEb5Yk"); The command freezes for 36 seconds. During the whole time, the network connection is maxed out (does it need to download THAT much data to get the info!?)

The code doesn't throw any exception. Here's the call stack while it is frozen. [Managed to Native Transition] System.dll!System.Net.Sockets.Socket.Receive(byte[] buffer, int offset, int size, System.Net.Sockets.SocketFlags socketFlags, out System.Net.Sockets.SocketError errorCode) System.dll!System.Net.Sockets.Socket.Receive(byte[] buffer, int offset, int size, System.Net.Sockets.SocketFlags socketFlags) System.dll!System.Net.Sockets.NetworkStream.Read(byte[] buffer, int offset, int size) System.dll!System.Net.PooledStream.Read(byte[] buffer, int offset, int size) System.dll!System.Net.ChunkParser.HandlePayload() System.dll!System.Net.ChunkParser.ProcessResponse() System.dll!System.Net.ChunkParser.Read(byte[] userBuffer, int userBufferOffset, int userBufferCount) System.dll!System.Net.ConnectStream.ReadWithoutValidation(byte[] buffer, int offset, int size, bool abortOnError) System.dll!System.Net.ConnectStream.Read(byte[] buffer, int offset, int size) System.dll!System.Net.WebClient.DownloadBitsState.RetrieveBytes(ref int bytesRetrieved) System.dll!System.Net.WebClient.DownloadBits(System.Net.WebRequest request, System.IO.Stream writeStream, System.Net.CompletionDelegate completionDelegate, System.ComponentModel.AsyncOperation asyncOp) System.dll!System.Net.WebClient.DownloadDataInternal(System.Uri address, out System.Net.WebRequest request) System.dll!System.Net.WebClient.DownloadString(System.Uri address) System.dll!System.Net.WebClient.DownloadString(string address) YoutubeExtractor.dll!YoutubeExtractor.HttpHelper.DownloadString(string url) YoutubeExtractor.dll!YoutubeExtractor.Decipherer.DecipherWithVersion(string cipher, string cipherVersion) YoutubeExtractor.dll!YoutubeExtractor.DownloadUrlResolver.GetDecipheredSignature(string htmlPlayerVersion, string signature) YoutubeExtractor.dll!YoutubeExtractor.DownloadUrlResolver.DecryptDownloadUrl(YoutubeExtractor.VideoInfo videoInfo) YoutubeExtractor.dll!YoutubeExtractor.DownloadUrlResolver.GetDownloadUrls(string videoUrl, bool decryptSignature) Natural Grounding Player.exe!Natural_Grounding_Player.frmYouTubeDownloader.btnGetInfo_Click(object sender, System.EventArgs e) Line 25 C#

Ahah! DecryptDownloadUrl shows up in the call stack. If I disable decryptSignature, it works instantly!

flagbug commented 10 years ago

The command freezes for 36 seconds. During the whole time, the network connection is maxed out (does it need to download THAT much data to get the info!?)

I think I know what's going on. The default behavior of GetDownloadUrls is to decrypt every encrypted signature it encounters. For a normal video, that's one request per resolution type, resulting in ~15 HTTP requests.

Pass false to the decryptSignature parameter and the signatures won't be automatically decrypted, if you need the actual decrypted download link for a video, call DecryptDownloadUrl on the video info.

mysteryx93 commented 10 years ago

Yes that's what I did and it works like a charm.