从提取的网址流式传输YouTube视频

时间:2016-05-09 13:55:15

标签: wpf video youtube streaming video-streaming

我正在尝试找到从http流播放YouTube视频的解决方案。不是嵌入式播放器或通过网站。这是因为我需要在应用程序中本地播放一些阻止嵌入的剪辑。 因此,获得http流的第一个任务很容易解决,例如使用YouTubeExtractor。例如,从这个youtube网址 https://www.youtube.com/watch?v=31crA53Dgu0

YouTubeExtractor提取下载视频的网址。正如您所看到的那样,没有具体的.mp4或.mov文件的路径。还有对IP的约束,因此该网址不会对您起作用。

https://r3---sn-puu8-3c2e.googlevideo.com:443/videoplayback?sparams=dur,gcr,id,initcwndbps,ip,ipbits,itag,lmt,mime,mm,mn,ms,mv,pl,ratebypass,requiressl,source,upn,expire&source=youtube&initcwndbps=3147500&pl=19&upn=oYYkSNBwoc8&fexp=9412913,9416126,9416891,9422596,9428398,9429016,9431012,9431364,9431901,9432206,9432825,9433096,9433424,9433623,9433946,9434085,9435504,9435703,9435937&id=o-AGanAaajMgOmp4VrXIwo9jewJnqlsvZecDxCcRpSN3lS&expire=1462821352&gcr=ua&ip=12.34.56.149&lmt=1458705532562546&ms=au&mt=1462799507&mv=m&dur=217.849&sver=3&itag=22&key=yt6&mn=sn-puu8-3c2e&mm=31&ipbits=0&mime=video/mp4&ratebypass=yes&requiressl=yes&signature=A142619EBA90D00CC46FF05B9CF1E3469B0EF196.072B532670A4D833582F94CF9C46F1F7D298F230&fallback_host=tc.v1.cache5.googlevideo.com

private string ExtractVideoUrl(string youtubeUrl)
    {
        IEnumerable<VideoInfo> videoInfos = DownloadUrlResolver.GetDownloadUrls(youtubeUrl, false);
        var video = videoInfos.First();
        if (video.RequiresDecryption)
        {
            DownloadUrlResolver.DecryptDownloadUrl(video);
        }

        return video.DownloadUrl;       // videoInfos.First().DownloadUrl;
    }

然后下载视频,这个lib使用下面的代码。有趣的时刻是阅读流和写入文件youtube视频的内容。

var request = (HttpWebRequest)WebRequest.Create(this.Video.DownloadUrl);
        if (this.BytesToDownload.HasValue)
        {
            request.AddRange(0, this.BytesToDownload.Value - 1);
        }

        // the following code is alternative, you may implement the function after your needs
        using (WebResponse response = request.GetResponse())
        {
            using (Stream source = response.GetResponseStream())
            {
            **// HOW to Play source stream???**
                using (FileStream target = File.Open(this.SavePath, FileMode.Create, FileAccess.Write))
                {
                    var buffer = new byte[1024];
                    bool cancel = false;
                    int bytes;
                    int copiedBytes = 0;

                    while (!cancel && (bytes = source.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        target.Write(buffer, 0, bytes);
                        .... 

所以一般的问题是如何从该开放流播放视频?例如,Chrome,Firefox和KMPlayer正在轻松实现这一目标。浏览器生成一个带有 video 标签的简单页面,因此通过JS管理播放器将是微不足道的。但是...内部WebBrowser控件不能,它建议下载文件。我尝试了CEFSharp(Chrome嵌入式框架)并且没有运气。 也许有人知道可以播放视频的好视频播放器WPF库吗?我也试过VLC.wpf和Shockwave Flash,但仍然不满意这个提取的网址。很多搜索但结果现在还不够。

1 个答案:

答案 0 :(得分:1)

经过2天的研究,我找到了如何直接从WPF应用程序播放youtube视频网址的解决方案。 之前的一些注意事项:

  • WPF的WebBrowser组件和WinForms的WebBrowser组件不支持HTML5。因此无法使用&lt; video&gt;播放视频在那里标记
  • Chrome嵌入式框架(CEF)及其CEFSharp包装器不支持&lt; audio&gt;和&lt;视频&gt;标签默认。正如我在found上所做的那样,需要重新编译CEF以支持音频,它似乎也是视频。 --enable-multimedia-streams选项根本不适用于播放视频
  • WPF MediaElement组件does not support播放视频流。但是存在workaroung,它们不适合播放youtube网址。
  • 找不到可以播放HttpWebRequest返回的Stream对象的视频的.NET媒体播放器

所以解决方案是使用GeckoFx webbrowser,它也可以通过nuget获得。由于它是基于WinForms的组件,因此需要使用WinFormsHosting在WPF中使用它。最终的解决方案是:

<xmlns:gecko="clr-namespace:Gecko;assembly=Geckofx-Winforms">
....
<WindowsFormsHost Width="400" Height="300" HorizontalAlignment="Stretch"  VerticalAlignment="Stretch" >
                <gecko:GeckoWebBrowser x:Name="_geckoBrowser"/>
            </WindowsFormsHost>

使用简单的代码:

public void PlayVideo(string videoId)
    {                        
        var url = string.Format("https://www.youtube.com/watch?v={0}", videoId);
        var videoUrl = ExtractVideoUrl(url);

        _geckoBrowser.Navigate(videoUrl);
    }

GeckoFx依赖于XulRunner运行时sdk。虽然安装了nuget包。此解决方案的一个缺点是所有应用程序依赖项的大小增加超过+ 70mb。