-
-
Notifications
You must be signed in to change notification settings - Fork 492
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Video downloads, but only audio, no video #777
Comments
Hi. I was not able to reproduce this. With the following code I got both audio and video: // Arrange
var youtube = new YoutubeClient();
using var dir = TempDir.Create();
var filePath = Path.Combine(dir.Path, "video.mp4");
// Act
await youtube.Videos.DownloadAsync(
"tllygkj0czw",
filePath,
o =>
o.SetFFmpegPath(FFmpeg.FilePath)
.SetContainer("mp4")
.SetPreset(ConversionPreset.UltraFast)
);
// Assert
MediaFormat.IsMp4File(filePath).Should().BeTrue(); |
@Tyrrrz Thanks for the reply. However, I'm stuck, as your code is basically the same as mine, with just the progress indicator removed, but when I run your code, I get the same as with my code, ie audio but no video. Any ideas? Thanks again. |
By the way, I had to remove the last line as |
That sounds weird. My only guess is that YouTube serves as different stream manifests for whatever reason. They tend to do regional-based A/B testing so it might be something like that. Can you try to resolve the manifest and inspect the streams it provides? Using this: https://github.com/Tyrrrz/YoutubeExplode#downloading-video-streams |
@Tyrrrz Thanks for the suggestion. What exactly am I looking for in there? I don't really know much about how the YouTube stuff works. Please clarify what info I need to look at to see what's being provided. Thanks again |
If you can just dump the contents of |
@Tyrrrz How is this...
Thanks again |
Hmm seems like it's lacking a lot of data. As an alternative, can just call |
@Tyrrrz Tried
Any other suggestions? Thanks again for the help. |
Looks fine to me. If you do a manual selection of streams, does anything change? |
@Tyrrrz Failed to start Thanks again |
await youtube.Videos.DownloadAsync(streamInfos, new ConversionRequestBuilder("video.mp4").SetFFmpegPath(FFmpeg.FilePath).Build()); |
@Tyrrrz Thanks, that worked fine. Is there any disadvantage to downloading this way? The page you linked says that stream muxing is a resource-intensive process, which concerns me. The previous method has worked for all videos I've tried, except for ones from this author. Is there some way of telling if the previous method will be OK, and only switching to this method if needed? Thanks again for all the help. |
Also, can I guarantee that there will always be a stream with label "1080p60", or do I have to loop through them all and pick the best one by parsing the label? |
There is no inherent disadvantage because the original approach uses this under the hood: YoutubeExplode/YoutubeExplode.Converter/ConversionExtensions.cs Lines 26 to 68 in 1b5b33e
When selecting streams manually, you have to account for a few different things. Reading the method implementation I linked should give more context. I don't know why the original approach didn't work for you and I can't reproduce it. The streams you receive seem fine. If you can get a video-less output with the manual approach as well, it could provide more info. But I don't have a guess right now.
No, you can't, that was just an example. |
@Tyrrrz Thanks again. I dumped out the
I tried the same code as before, but used However, this leaves me with a problem. How do I know which stream to pick? I can't pick the highest resolution, as that fails as you can see here. Is there a way of telling which stream will give the video as well? Any advice? Thanks again. |
Hmm. Can you download the |
@Tyrrrz Tried the following... string _path = @"C:\Users\Public\Downloads\";
var youtube = new YoutubeClient();
var videoUrl = "https://youtube.com/watch?v=tllygkj0czw";
var streamManifest = await youtube.Videos.Streams.GetManifestAsync(videoUrl);
var videoStreamInfo = streamManifest
.GetVideoStreams()
.Where(s => s.Container == Container.Mp4)
.First(s => s.VideoQuality.Label == "1440p60");
await youtube.Videos.Streams.DownloadAsync(videoStreamInfo, $"{_path}video.mp4"); ...but the file that was downloaded wouldn't play. Media Player gave an error "We can't open video. It's encoded in AVI format which isn't supported." Does that help? Thanks again. |
It really looks like YouTube just has a corrupted/broken stream for some reason. |
It's odd, as it seems to happen with all of the videos from that author, but I've not noticed it with any other author. So, I'm still left with my previous question, is there any way of telling whether a stream is going to have video or not? If I could detect that, I could choose the right stream. Otherwise I'm stuck. Thanks again |
What's the |
@Tyrrrz Not exactly sure how to find the var videoStreamInfo = streamManifest
.GetVideoStreams()
.Where(s => s.Container == Container.Mp4)
.First(s => s.VideoQuality.Label == "1440p60");
Console.WriteLine($"Codec: {videoStreamInfo.VideoCodec}");
Console.WriteLine($"Bit rate: {videoStreamInfo.Bitrate.ToString()}");
Console.WriteLine($"Size: {videoStreamInfo.Size.Bytes} bytes");
Console.WriteLine($"Container: {videoStreamInfo.Container.Name}");
Console.WriteLine($"Url: {videoStreamInfo.Url}"); ...gave the following output...
Pasting that URL into a browser played the video without any audio. Does that help? If not, please can you give me more precise instructions how to get the info you want. Thanks again |
Can you download that stream and upload it here? |
@Tyrrrz Short answer - no I don't seem to be able to download it. I have tried a few ways, but all time out. I used the URL returned by the code above (regenerated as they only last a short while), but whatever C# I try, it just times out. I first tried this... HttpClient client=new();
var bytes = await client.GetByteArrayAsync(url)
File.WriteAllBytes(@"C:\Users\Public\Downloads\stream.mp4", bytes); I then tried the old method... WebRequest r=WebRequest.Create(url);
using WebResponse res=r.GetResponse();
using Stream s=res.GetResponseStream();
string file=@"C:\Users\Public\Downloads\stream.mp4";
using var fs = new FileStream(file, FileMode.OpenOrCreate);
s.CopyTo(fs); ...but had the same time-out issue both ways. The code shown earlier downloaded the file fairly quickly, so it's not the size that's a problem. Am I doing something wrong here? Any suggestions? Thanks again |
What if you try to download it in your browser? You said you could get it to play there, right? |
@Tyrrrz Silly me. Forgot that I could just paste the URL into a browser and download from there 😁 Too big to upload here, so I put it on my blog. |
The stream looks actually fine so I'm not sure what's wrong then |
Do you have any advice as to what I can do then? I've asked a few times if there is a way of checking a stream to see if it contains the data I need, but you've not answered that one, which makes me think it can't be done. I really need a way of getting the full audio and video, so any advice would be appreciated. |
Yeah, I was trying to figure out if there's anything special about that stream that could let you identify it early and skip, but it doesn't appear like it's special in any way. So I unfortunately don't have any recommendations for that. As an interim solution, I would specifically skip this combination of video quality + video codec + container for this YouTube creator. I wish I could assist you help more but I don't have the time to investigate this further. |
@Tyrrrz OK, thanks for all the help. |
Closing as I was not able to personally reproduce this issue. |
Version
6.3.12
Platform
LinqPad on Windows 11
Steps to reproduce
Start LinqPad, set the language to "C# Statements", add a reference to the Nuget package and paste the following code in...
The file that is downloaded plays fine, but you only get audio, no video.
Note that this code works fine for most videos, it's only ones by this author that give this problem (as far as I know). If you try it with other videos (such as this classic) it works fine.
Any ideas? Thanks
Details
See above
Checklist
The text was updated successfully, but these errors were encountered: