从提取的 url 流式传输 YouTube 视频
Stream YouTube video from extracted url
我正在尝试寻找从 http 流播放 YouTube 视频的解决方案。不是作为嵌入式播放器或通过网站。原因是我需要在阻止嵌入的应用程序中本地播放一些剪辑。
所以获取http流的第一个任务很容易解决,例如使用 YouTubeExtractor。例如来自这个 youtube url
https://www.youtube.com/watch?v=31crA53Dgu0
YouTubeExtractor 提取此类 url 用于下载视频。如您所见,没有指向具体 .mp4 或 .mov 文件的路径。还有绑定到 IP,所以 url 对你不起作用。
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;
}
然后下载视频这个库使用下面的代码。有趣的时刻是在读取流和写入文件的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 Embeded Framework) and no luck there. Maybe anybody know good video player WPF library which can streaming video? I also tried VLC.wpf 和 Shockwave Flash,但仍然对这个提取的 url 不满意。大量搜索,但目前结果不足。
经过 2 天的研究,我找到了如何直接从 WPF 应用程序播放 youtube 视频的解决方案 url。
之前的一些笔记:
- WPF 和 WinForms 的 WebBrowser 组件不支持 HTML5。所以无法使用
- Chrome 嵌入式框架 (CEF) 及其 CEFSharp 包装器默认不支持
- WPF MediaElement 组件does not support 从流中播放视频。不过也有变通方法存在,它们不适合播放 youtube url 的。
- 未找到可以播放来自 HttpWebRequest 返回的 Stream 对象的视频的 .NET 媒体播放器
所以解决方案是使用 GeckoFx webbrowser which is also available via nuget. As it is WinForms based component it is needed to use 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。
我正在尝试寻找从 http 流播放 YouTube 视频的解决方案。不是作为嵌入式播放器或通过网站。原因是我需要在阻止嵌入的应用程序中本地播放一些剪辑。 所以获取http流的第一个任务很容易解决,例如使用 YouTubeExtractor。例如来自这个 youtube url https://www.youtube.com/watch?v=31crA53Dgu0
YouTubeExtractor 提取此类 url 用于下载视频。如您所见,没有指向具体 .mp4 或 .mov 文件的路径。还有绑定到 IP,所以 url 对你不起作用。
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;
}
然后下载视频这个库使用下面的代码。有趣的时刻是在读取流和写入文件的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 Embeded Framework) and no luck there. Maybe anybody know good video player WPF library which can streaming video? I also tried VLC.wpf 和 Shockwave Flash,但仍然对这个提取的 url 不满意。大量搜索,但目前结果不足。
经过 2 天的研究,我找到了如何直接从 WPF 应用程序播放 youtube 视频的解决方案 url。 之前的一些笔记:
- WPF 和 WinForms 的 WebBrowser 组件不支持 HTML5。所以无法使用
- Chrome 嵌入式框架 (CEF) 及其 CEFSharp 包装器默认不支持
- WPF MediaElement 组件does not support 从流中播放视频。不过也有变通方法存在,它们不适合播放 youtube url 的。
- 未找到可以播放来自 HttpWebRequest 返回的 Stream 对象的视频的 .NET 媒体播放器
所以解决方案是使用 GeckoFx webbrowser which is also available via nuget. As it is WinForms based component it is needed to use 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。