Vlc.DotNet 視頻畫面拉伸滿整個控件的方法
引用Vlc.DotNet
根據官方的例子,首先下載VLC,把VLC裏面的各種dll拷貝到輸出目錄裏面,然後安裝Nuget包Vlc.DotNet.Core.Interops ,Vlc.DotNet.Core,根據程序的類型選擇用Vlc.DotNet.Forms還是Vlc.DotNet.Wpf。具體教程網上有很多例子。相信各位搜索到這個問題也是把環境已經搭好了。
實現代碼
這裏我的程序用的是Wpf,直接上效果。
xaml代碼如下
基本上和官方的示例代碼一樣
<Window x:Class="VLCTest.DemoWin"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:wpf="clr-namespace:Vlc.DotNet.Wpf;assembly=Vlc.DotNet.Wpf"
xmlns:local="clr-namespace:VLCTest"
mc:Ignorable="d"
Title="DemoWin" Height="450" Width="800">
<Grid>
<ContentControl Width="400" Height="400" Name="Container">
<wpf:VlcControl x:Name="VlcControl" />
</ContentControl>
<Button Content="Stop" HorizontalAlignment="Left" Margin="664,360,0,0" VerticalAlignment="Top" Width="75" Click="StopPlay"/>
</Grid>
</Window>
播放代碼如下
private void Play()
{
string path = @"D:\TestFiles\TestVideo.mp4";
string currentDirectory = Directory.GetCurrentDirectory();
DirectoryInfo vlcDirectory = new DirectoryInfo(System.IO.Path.Combine(currentDirectory, "VLC"));
VlcControl.SourceProvider.CreatePlayer(vlcDirectory);
FileInfo playFile = new FileInfo(path);
// 這裏把幀圖像拉伸成填滿整個控件
var viewBox = VlcControl.Content as Viewbox;
viewBox.Stretch = System.Windows.Media.Stretch.Fill;
VlcControl.SourceProvider.MediaPlayer.Play(playFile);
}
這裏可以看到,只要把控件裏面的ViewBox拉伸模式改成Fill填滿整個控件即可。
實現思路
這裏先要感謝這位大佬的文章爲我提供了思路。
參考:https://my.oschina.net/duoing/blog/1499664
要實現視頻畫面填滿整個控件的效果,其實就是要吧視頻的輸出橫縱比改變。這裏有兩種思路:
1.視頻流渲染成畫面的時侯就按一定的橫縱比渲染然後縮放。這就需要在調用VLC時通過參數或者調用改變橫縱比的方法實現。
2.拿到渲染的每一幀畫面後,在呈現到界面之前,對畫面進行縮放調整橫縱比然後再輸出到畫面上。這中方案就要靠界面程序來實現,靠也就是我們自己寫的程序對每一幀畫面再加工一次然後輸出。
以上代碼採用的是第二種方案。
方案對比
第一種方案明顯比第二種方案更節約性能,因爲它在源頭就把幀畫面渲染好了。第二種方案雖然多了一個拉伸畫面的操作,但是它不需要深入地瞭解VLC內部的實現機制。總的來說,第二種方案其實屬於取巧的方案,遇到多區域播放或者播放高分辨率視頻的時候可能還是會有卡頓。
踩坑記錄
一開始決定自己拉伸幀畫面的時候,我的第一想法就先看看Vlc.dotnet.Wpf 源碼中VlcControl 這個控件是怎麼實現的,結果一看發現代碼不多,才幾十行。雖然說是幾十行,但還是十分硬核,作者把幀渲染和呈現完全分離開,在控件裏就只負責把拿到的畫面丟到Image裏面,然後綁定渲染源,每變化一幀就改變畫面。
部分源碼
/// <summary>
/// The constructor
/// </summary>
public VlcControl()
{
sourceProvider = new VlcVideoSourceProvider(this.Dispatcher);
this.viewBox = new Viewbox
{
Child = this.videoContent,
Stretch = Stretch.Uniform
};
this.Content = this.viewBox;
this.Background = Brushes.Black;
// Binds the VideoSource to the Image.Source property
this.videoContent.SetBinding(Image.SourceProperty, new Binding(nameof(VlcVideoSourceProvider.VideoSource)) { Source = sourceProvider });
}
剛剛好這裏的VlcControl是繼承於UserControl控件,裏面的Content就是ViewBox,把ViewBox的拉伸模式改成Fill就剛好能實現效果。
最後感謝一下Vlc.dotnet 作者的良好設計和開源精神,站在巨人的肩膀上我們纔看得更遠。
Vlc.dotnet 源碼:https://github.com/ZeBobo5/Vlc.DotNet/tree/develop/src
如果這篇文章有幸幫助到你,請不要吝嗇你的贊。