...
 
Commits (55)
......@@ -12,13 +12,13 @@
<DefineConstants>$(DefineConstants);NET471;NET</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="$(TargetFramework.StartsWith('Xamarin.iOS'))">
<DefineConstants>$(DefineConstants);MONO;IOS;COCOA</DefineConstants>
<DefineConstants>$(DefineConstants);MONO;IOS;APPLE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="$(TargetFramework.StartsWith('Xamarin.Mac'))">
<DefineConstants>$(DefineConstants);MONO;MAC;COCOA</DefineConstants>
<DefineConstants>$(DefineConstants);MONO;MAC;APPLE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="$(TargetFramework.StartsWith('Xamarin.TVOS'))">
<DefineConstants>$(DefineConstants);MONO;TVOS;COCOA</DefineConstants>
<DefineConstants>$(DefineConstants);MONO;TVOS;APPLE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="$(TargetFramework.StartsWith('MonoAndroid'))">
<DefineConstants>$(DefineConstants);MONO;ANDROID</DefineConstants>
......@@ -26,4 +26,7 @@
<PropertyGroup Condition="$(TargetFramework.StartsWith('uap'))">
<DefineConstants>$(DefineConstants);UWP;NET</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'uap10.0'">
<DefineConstants>$(DefineConstants);UWP10_0</DefineConstants>
</PropertyGroup>
</Project>
\ No newline at end of file
......@@ -2,32 +2,15 @@
<PropertyGroup>
<Title>LibVLCSharp.Forms.GTK</Title>
<Summary>GTK integration for LibVLCSharp.Forms</Summary>
<Description>LibVLCSharp is a cross-platform audio and video API for .NET platforms based on VideoLAN's LibVLC Library.
It provides a comprehensive multimedia API that can be used across mobile, server and desktop to render video and output audio. Mono, .NET Framework and .NET Core runtimes are supported.
<Description>LibVLCSharp is a cross-platform audio and video API for .NET platforms based on VideoLAN's LibVLC Library. It provides a comprehensive multimedia API that can be used across mobile, server and desktop to render video and output audio. Mono, .NET Framework and .NET Core runtimes are supported.
LibVLCSharp.Forms.GTK contains the Xamarin.Forms support for LibVLCSharp through custom renderers on the GTK platform. It depends on LibVLCSharp.Forms and LibVLCSharp.GTK.
Supported platforms:
- Xamarin.Android
- Xamarin.iOS
- Xamarin.Mac
- Windows (WPF/WinForms)
- Xamarin.Forms
- .NET Standard 1.1
- .NET Core
Features:
- Network browsing for distant filesystems (SMB, FTP, SFTP, NFS...).
- HDMI passthrough for Audio HD codecs, like E-AC3, TrueHD or DTS-HD.
- Stream to distant renderers, like Chromecast.
- 360 video and 3D audio playback with viewpoint change.
- Support for Ambisonics audio and more than 8 audio channels.
- Subtitles size modification live.
- Hardware decoding and display on all platforms.
- DVD playback and menu navigation.
</Description>
Xamarin.Forms support for other platforms are in different packages (namely LibVLCSharp.Forms and LibVLCSharp.Forms.WPF). LibVLC needs to be installed separately, see VideoLAN.LibVLC.* packages.
</Description>
<TargetFramework>net47</TargetFramework>
<RootNamespace>LibVLCSharp.Forms.Platforms.GTK</RootNamespace>
<PackageVersion>0.8.1</PackageVersion>
<Version>3.0.2</Version>
<PackageId>LibVLCSharp.Forms.GTK</PackageId>
<Authors>VideoLAN</Authors>
<Owners>VideoLAN</Owners>
......
......@@ -2,32 +2,15 @@
<PropertyGroup>
<Title>LibVLCSharp.Forms.WPF</Title>
<Summary>WPF integration for LibVLCSharp.Forms</Summary>
<Description>LibVLCSharp is a cross-platform audio and video API for .NET platforms based on VideoLAN's LibVLC Library.
It provides a comprehensive multimedia API that can be used across mobile, server and desktop to render video and output audio. Mono, .NET Framework and .NET Core runtimes are supported.
<Description>LibVLCSharp is a cross-platform audio and video API for .NET platforms based on VideoLAN's LibVLC Library. It provides a comprehensive multimedia API that can be used across mobile, server and desktop to render video and output audio. Mono, .NET Framework and .NET Core runtimes are supported.
Supported platforms:
- Xamarin.Android
- Xamarin.iOS
- Xamarin.Mac
- Windows (WPF/WinForms)
- Xamarin.Forms
- .NET Standard 1.1
- .NET Core
LibVLCSharp.Forms.WPF contains the Xamarin.Forms support for LibVLCSharp through custom renderers on the WPF platform. It depends on LibVLCSharp.Forms and LibVLCSharp.WPF.
Features:
- Network browsing for distant filesystems (SMB, FTP, SFTP, NFS...).
- HDMI passthrough for Audio HD codecs, like E-AC3, TrueHD or DTS-HD.
- Stream to distant renderers, like Chromecast.
- 360 video and 3D audio playback with viewpoint change.
- Support for Ambisonics audio and more than 8 audio channels.
- Subtitles size modification live.
- Hardware decoding and display on all platforms.
- DVD playback and menu navigation.
</Description>
Xamarin.Forms support for other platforms are in different packages (namely LibVLCSharp.Forms and LibVLCSharp.Forms.GTK). LibVLC needs to be installed separately, see VideoLAN.LibVLC.* packages.
</Description>
<TargetFramework>net47</TargetFramework>
<RootNamespace>LibVLCSharp.Forms.Platforms.WPF</RootNamespace>
<PackageVersion>0.8.1</PackageVersion>
<Version>3.0.2</Version>
<PackageId>LibVLCSharp.Forms.WPF</PackageId>
<Authors>VideoLAN</Authors>
<Owners>VideoLAN</Owners>
......
......@@ -2,35 +2,21 @@
<PropertyGroup>
<Title>LibVLCSharp.Forms</Title>
<Summary>Xamarin.Forms integration for LibVLCSharp</Summary>
<Description>LibVLCSharp is a cross-platform audio and video API for .NET platforms based on VideoLAN's LibVLC Library.
It provides a comprehensive multimedia API that can be used across mobile, server and desktop to render video and output audio. Mono, .NET Framework and .NET Core runtimes are supported.
<Description>LibVLCSharp is a cross-platform audio and video API for .NET platforms based on VideoLAN's LibVLC Library. It provides a comprehensive multimedia API that can be used across mobile, server and desktop to render video and output audio. Mono, .NET Framework and .NET Core runtimes are supported.
LibVLCSharp.Forms contains the Xamarin.Forms support for LibVLCSharp through custom renderers. It depends on LibVLCSharp and brings Xamarin.Forms support for:
- Android,
- iOS,
- Mac.
Supported platforms:
- Xamarin.Android
- Xamarin.iOS
- Xamarin.Mac
- Windows (WPF/WinForms)
- Xamarin.Forms
- .NET Standard 1.1
- .NET Core
Features:
- Network browsing for distant filesystems (SMB, FTP, SFTP, NFS...).
- HDMI passthrough for Audio HD codecs, like E-AC3, TrueHD or DTS-HD.
- Stream to distant renderers, like Chromecast.
- 360 video and 3D audio playback with viewpoint change.
- Support for Ambisonics audio and more than 8 audio channels.
- Subtitles size modification live.
- Hardware decoding and display on all platforms.
- DVD playback and menu navigation.
Xamarin.Forms support for GTK and WPF are in separate packages. LibVLC needs to be installed separately, see VideoLAN.LibVLC.* packages.
</Description>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
<TargetFrameworks Condition="!$([MSBuild]::IsOsPlatform('Linux'))">$(TargetFrameworks);MonoAndroid81;Xamarin.iOS10;Xamarin.Mac20</TargetFrameworks>
<RootNamespace>LibVLCSharp.Forms</RootNamespace>
<NeutralLanguage>en</NeutralLanguage>
<LangVersion>7.3</LangVersion>
<Version>0.8.1</Version>
<Version>3.0.2</Version>
<PackageId>LibVLCSharp.Forms</PackageId>
<Authors>VideoLAN</Authors>
<Owners>VideoLAN</Owners>
......
......@@ -20,24 +20,24 @@ namespace LibVLCSharp.Forms.Platforms.Android
{
base.OnElementChanged(e);
if (Control == null)
if (e.NewElement != null)
{
SetNativeControl(new LibVLCSharp.Platforms.Android.VideoView(Context));
if (Control == null)
{
SetNativeControl(new LibVLCSharp.Platforms.Android.VideoView(Context));
e.NewElement.MediaPlayerChanging += OnMediaPlayerChanging;
if (Control.MediaPlayer != e.NewElement.MediaPlayer)
{
OnMediaPlayerChanging(this, new MediaPlayerChangingEventArgs(Control.MediaPlayer, e.NewElement.MediaPlayer));
}
}
}
if (e.OldElement != null)
{
e.OldElement.MediaPlayerChanging -= OnMediaPlayerChanging;
}
if (e.NewElement != null)
{
e.NewElement.MediaPlayerChanging += OnMediaPlayerChanging;
if (Control.MediaPlayer != e.NewElement.MediaPlayer)
{
OnMediaPlayerChanging(this, new MediaPlayerChangingEventArgs(Control.MediaPlayer, e.NewElement.MediaPlayer));
}
}
}
}
private void OnMediaPlayerChanging(object sender, MediaPlayerChangingEventArgs e)
......
......@@ -15,24 +15,24 @@ namespace LibVLCSharp.Forms.Platforms.Mac
{
base.OnElementChanged(e);
if (Control == null)
if (e.NewElement != null)
{
SetNativeControl(new LibVLCSharp.Platforms.Mac.VideoView());
if (Control == null)
{
SetNativeControl(new LibVLCSharp.Platforms.Mac.VideoView());
e.NewElement.MediaPlayerChanging += OnMediaPlayerChanging;
if (Control.MediaPlayer != e.NewElement.MediaPlayer)
{
OnMediaPlayerChanging(this, new MediaPlayerChangingEventArgs(Control.MediaPlayer, e.NewElement.MediaPlayer));
}
}
}
if (e.OldElement != null)
{
e.OldElement.MediaPlayerChanging -= OnMediaPlayerChanging;
}
if (e.NewElement != null)
{
e.NewElement.MediaPlayerChanging += OnMediaPlayerChanging;
if (Control.MediaPlayer != e.NewElement.MediaPlayer)
{
OnMediaPlayerChanging(this, new MediaPlayerChangingEventArgs(Control.MediaPlayer, e.NewElement.MediaPlayer));
}
}
}
private void OnMediaPlayerChanging(object sender, MediaPlayerChangingEventArgs e)
......
using LibVLCSharp.Shared;
using LibVLCSharp.Forms.Platforms.iOS;
using LibVLCSharp.Forms.Shared;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using UIKit;
using System;
using Foundation;
[assembly: ExportRenderer(typeof(LibVLCSharp.Forms.Shared.VideoView), typeof(VideoViewRenderer))]
namespace LibVLCSharp.Forms.Platforms.iOS
{
[Preserve(AllMembers = true)]
public class VideoViewRenderer : ViewRenderer<LibVLCSharp.Forms.Shared.VideoView, LibVLCSharp.Platforms.iOS.VideoView>
{
protected override void OnElementChanged(ElementChangedEventArgs<LibVLCSharp.Forms.Shared.VideoView> e)
{
base.OnElementChanged(e);
if(Control == null)
if (e.NewElement != null)
{
SetNativeControl(new LibVLCSharp.Forms.Platforms.iOS.VideoView());
if (Control == null)
{
SetNativeControl(new LibVLCSharp.Platforms.iOS.VideoView());
e.NewElement.MediaPlayerChanging += OnMediaPlayerChanging;
if (Control.MediaPlayer != e.NewElement.MediaPlayer)
{
OnMediaPlayerChanging(this, new MediaPlayerChangingEventArgs(Control.MediaPlayer, e.NewElement.MediaPlayer));
}
}
}
if (e.OldElement != null)
{
e.OldElement.MediaPlayerChanging -= OnMediaPlayerChanging;
}
if (e.NewElement != null)
{
e.NewElement.MediaPlayerChanging += OnMediaPlayerChanging;
if (Control.MediaPlayer != e.NewElement.MediaPlayer)
{
OnMediaPlayerChanging(this, new MediaPlayerChangingEventArgs(Control.MediaPlayer, e.NewElement.MediaPlayer));
}
}
}
private void OnMediaPlayerChanging(object sender, MediaPlayerChangingEventArgs e)
......@@ -42,26 +41,4 @@ namespace LibVLCSharp.Forms.Platforms.iOS
Control.MediaPlayer = e.NewMediaPlayer;
}
}
public class VideoView : LibVLCSharp.Platforms.iOS.VideoView, IVisualElementRenderer
{
public VisualElement Element { get; private set; }
public UIView NativeView => this;
public UIViewController ViewController => ViewController;
public event EventHandler<VisualElementChangedEventArgs> ElementChanged;
public SizeRequest GetDesiredSize(double widthConstraint, double heightConstraint) => this.GetSizeRequest(widthConstraint, heightConstraint);
public void SetElement(VisualElement element)
{
Element = element;
ElementChanged?.Invoke(this, new VisualElementChangedEventArgs(null, Element));
}
public void SetElementSize(Size size) => Element.Layout(new Rectangle(Element.X, Element.Y, size.Width, size.Height));
}
}
\ No newline at end of file
......@@ -2,20 +2,19 @@
<PropertyGroup>
<Title>LibVLCSharp.GTK</Title>
<Summary>GTK integration for LibVLCSharp</Summary>
<Description>The official GTK# (mono/gtk-sharp) views for LibVLCSharp.
<Description>LibVLCSharp is a cross-platform audio and video API for .NET platforms based on VideoLAN's LibVLC Library. It provides a comprehensive multimedia API that can be used across mobile, server and desktop to render video and output audio. Mono, .NET Framework and .NET Core runtimes are supported.
LibVLCSharp.GTK contains the integration with GTK# (mono/gtk-sharp).
This package contains the views that allows to display a video played with LibVLCSharp
in a GTK# app.
LibVLCSharp.Forms.Platforms.GTK depends on this package.
This package depends on LibVLCSharp.
This package depends on LibVLCSharp. If you need Xamarin.Forms support for your GTK app, see LibVLCSharp.Forms.Platforms.GTK (which depends on this package).
libvlc needs to be installed separately.
LibVLC needs to be installed separately, see VideoLAN.LibVLC.* packages.
</Description>
<TargetFramework>net47</TargetFramework>
<RootNamespace>LibVLCSharp.GTK</RootNamespace>
<Version>0.8.1</Version>
<Version>3.0.2</Version>
<PackageId>LibVLCSharp.GTK</PackageId>
<Authors>VideoLAN</Authors>
<Owners>VideoLAN</Owners>
......
......@@ -2,34 +2,20 @@
<PropertyGroup>
<Title>LibVLCSharp.WPF</Title>
<Summary>WPF integration for LibVLCSharp</Summary>
<Description>LibVLCSharp is a cross-platform audio and video API for .NET platforms based on VideoLAN's LibVLC Library.
It provides a comprehensive multimedia API that can be used across mobile, server and desktop to render video and output audio. Mono, .NET Framework and .NET Core runtimes are supported.
<Description>LibVLCSharp is a cross-platform audio and video API for .NET platforms based on VideoLAN's LibVLC Library. It provides a comprehensive multimedia API that can be used across mobile, server and desktop to render video and output audio. Mono, .NET Framework and .NET Core runtimes are supported.
LibVLCSharp.WPF contains the integration with Windows Presentation Foundation (WPF).
Supported platforms:
- Xamarin.Android
- Xamarin.iOS
- Xamarin.Mac
- Windows (WPF/WinForms)
- Xamarin.Forms
- .NET Standard 1.1
- .NET Core
This package contains the views that allows to display a video played with LibVLCSharp
in a WPF app. It depends on LibVLCSharp.
Features:
- Network browsing for distant filesystems (SMB, FTP, SFTP, NFS...).
- HDMI passthrough for Audio HD codecs, like E-AC3, TrueHD or DTS-HD.
- Stream to distant renderers, like Chromecast.
- 360 video and 3D audio playback with viewpoint change.
- Support for Ambisonics audio and more than 8 audio channels.
- Subtitles size modification live.
- Hardware decoding and display on all platforms.
- DVD playback and menu navigation.
</Description>
LibVLC needs to be installed separately, see VideoLAN.LibVLC.* packages.
</Description>
<TargetFramework>net461</TargetFramework>
<RootNamespace>LibVLCSharp.WPF</RootNamespace>
<NeutralLanguage>en</NeutralLanguage>
<LangVersion>7.3</LangVersion>
<Version>0.8.1</Version>
<Version>3.0.2</Version>
<PackageId>LibVLCSharp.WPF</PackageId>
<UseWPF>true</UseWPF>
<Authors>VideoLAN</Authors>
......
# LibVLCSharp.WPF
[![NuGet Stats](https://img.shields.io/nuget/v/LibVLCSharp.WPF.svg)](https://www.nuget.org/packages/LibVLCSharp.WPF)
[![NuGet Stats](https://img.shields.io/nuget/dt/LibVLCSharp.WPF.svg)](https://www.nuget.org/packages/LibVLCSharp.WPF)
LibVLCSharp.WPF is the WPF integration for LibVLCSharp.
It contains the views that allow to display a video played with [LibVLCSharp](../LibVLCSharp/README.md)
in a WPF app.
[LibVLCSharp.Forms.Platforms.WPF](../LibVLCSharp.Forms.Platforms.WPF) depends on this package.
This package depends on [LibVLCSharp](../LibVLCSharp/README.md).
Supported framework:
- net461+
Supported platform:
- Windows
## Airspace limitations
If you encounter UI issues with the WPF VideoView in your application, you may be running into what is called _airspace_ limitations.
For context and explanations of the tradeoffs, see this [PR](https://github.com/videolan/libvlcsharp/pull/1).
Issues related to airspace are tracked on our GitLab with the [airspace](https://code.videolan.org/videolan/LibVLCSharp/issues?scope=all&utf8=%E2%9C%93&state=all&label_name[]=airspace) tag.
## WPF control specific stuffs
Due to the Airspace issue, you cannot easily draw things over the video in WPF, unless you have a hack like the one that is included in this project.
This hack means that the WPF control works a little differently than other platform's.
If you want to place something over the control, you would probably write code like this in other platforms:
```xml
<Grid>
<vlc:VideoView x:Name="VideoView" />
<Button Click="Play_Clicked">PLAY</Button>
</Grid>
```
But for WPF, you would rather need something like this:
```xml
<Grid>
<vlc:VideoView x:Name="VideoView">
<Button Click="Play_Clicked">PLAY</Button>
</vlc:VideoView>
</Grid>
```
The `VideoView` appears as a container in your XAML (you can set its `Content` property from code too), but it is really a detached window over your video control.
The DataContext of the `VideoView` is propagated to your overlay content. This means you can inherit the `DataContext` environment from the outside of your `VideoView`
*Note : This behavior is specific to the LibVLCSharp WPF implementation and is not (yet?) available to LibVLCSharp.Forms.Platforms.WPF*
## Why should I reference this package in my project?
If you want to create a video application using WPF and any supported .NET language, this package is made for you.
You can also create a true cross-platform application with Xamarin.Forms, and use the WPF backend.
In that case, you would need the [LibVLCSharp.Forms.Platforms.WPF](../LibVLCSharp.Forms.Platforms.WPF) package instead, which internally references this one.
For other platforms, see the [main documentation](../README.md).
......@@ -60,7 +60,8 @@ namespace LibVLCSharp.WPF
{
ForegroundWindow = new ForegroundWindow(windowsFormsHost)
{
Content = ViewContent
Content = ViewContent,
DataContext = windowsFormsHost.DataContext
};
}
......
......@@ -2,26 +2,18 @@
<PropertyGroup>
<Title>LibVLCSharp.WinForms</Title>
<Summary>WinForms integration for LibVLCSharp</Summary>
<Description>
LibVLCSharp is a cross-platform audio and video API for .NET platforms based on VideoLAN's LibVLC Library.
<Description>LibVLCSharp is a cross-platform audio and video API for .NET platforms based on VideoLAN's LibVLC Library. It provides a comprehensive multimedia API that can be used across mobile, server and desktop to render video and output audio. Mono, .NET Framework and .NET Core runtimes are supported.
LibVLCSharp.WinForms contains the integration with Windows Forms.
It provides a comprehensive multimedia API that can be used across mobile, server and desktop to render video and output audio. Mono, .NET Framework and .NET Core runtimes are supported.
This package contains the views that allows to display a video played with LibVLCSharp
in a Windows Forms app. It depends on LibVLCSharp.
Use this package in your WinForms project to get a VideoView with LibVLCSharp integration.
Features:
- Network browsing for distant filesystems (SMB, FTP, SFTP, NFS...).
- HDMI passthrough for Audio HD codecs, like E-AC3, TrueHD or DTS-HD.
- Stream to distant renderers, like Chromecast.
- 360 video and 3D audio playback with viewpoint change.
- Support for Ambisonics audio and more than 8 audio channels.
- Subtitles size modification live.
- Hardware decoding and display on all platforms.
- DVD playback and menu navigation.
LibVLC needs to be installed separately, see VideoLAN.LibVLC.* packages.
</Description>
<TargetFrameworks>net40</TargetFrameworks>
<RootNamespace>LibVLCSharp.WinForms</RootNamespace>
<Version>0.8.1</Version>
<Version>3.0.2</Version>
<PackageId>LibVLCSharp.WinForms</PackageId>
<Authors>VideoLAN</Authors>
<Owners>VideoLAN</Owners>
......
# LibVLCSharp.WinForms
[![NuGet Stats](https://img.shields.io/nuget/v/LibVLCSharp.WinForms.svg)](https://www.nuget.org/packages/LibVLCSharp.WinForms)
[![NuGet Stats](https://img.shields.io/nuget/dt/LibVLCSharp.WinForms.svg)](https://www.nuget.org/packages/LibVLCSharp.WPF)
LibVLCSharp.WinForms is the WinForms integration for LibVLCSharp.
It contains the views that allow to display a video played with [LibVLCSharp](../LibVLCSharp/README.md)
in a Windows Forms app.
This package depends on [LibVLCSharp](../LibVLCSharp/README.md).
Supported framework:
- net40+
Supported platform:
- Windows
## Why should I reference this package in my project?
If you want to create a video application using Windows Forms and any supported .NET language, this package is made for you.
For other platforms, see the [main documentation](../README.md).

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.0
VisualStudioVersion = 15.0.28307.705
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibVLCSharp", "LibVLCSharp\LibVLCSharp.csproj", "{D1C3B7C4-713B-46B2-B33A-E9298C819921}"
EndProject
......@@ -65,6 +65,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibVLCSharp.WinForms.Sample
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibVLCSharp.UWP.Sample", "Samples\LibVLCSharp.UWP.Sample\LibVLCSharp.UWP.Sample.csproj", "{B0796D95-FA72-4154-9668-1F939BF03816}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibVLCSharp.D3DCallbacks", "Samples\LibVLCSharp.D3DCallbacks\LibVLCSharp.D3DCallbacks.csproj", "{2182D09E-594C-472D-BB15-37ECEAA9DD22}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibVLCSharp.D3DCallbacks.Texture", "Samples\LibVLCSharp.D3DCallbacks.Texture\LibVLCSharp.D3DCallbacks.Texture.csproj", "{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
......@@ -1579,6 +1583,118 @@ Global
{B0796D95-FA72-4154-9668-1F939BF03816}.Release|x86.ActiveCfg = Release|x86
{B0796D95-FA72-4154-9668-1F939BF03816}.Release|x86.Build.0 = Release|x86
{B0796D95-FA72-4154-9668-1F939BF03816}.Release|x86.Deploy.0 = Release|x86
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Ad-Hoc|ARM64.ActiveCfg = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Ad-Hoc|ARM64.Build.0 = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.AppStore|ARM.Build.0 = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.AppStore|ARM64.ActiveCfg = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.AppStore|ARM64.Build.0 = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.AppStore|iPhone.Build.0 = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.AppStore|x64.ActiveCfg = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.AppStore|x64.Build.0 = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.AppStore|x86.ActiveCfg = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.AppStore|x86.Build.0 = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Debug|ARM.ActiveCfg = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Debug|ARM.Build.0 = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Debug|ARM64.Build.0 = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Debug|iPhone.Build.0 = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Debug|x64.ActiveCfg = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Debug|x64.Build.0 = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Debug|x86.ActiveCfg = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Debug|x86.Build.0 = Debug|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Release|Any CPU.Build.0 = Release|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Release|ARM.ActiveCfg = Release|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Release|ARM.Build.0 = Release|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Release|ARM64.ActiveCfg = Release|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Release|ARM64.Build.0 = Release|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Release|iPhone.ActiveCfg = Release|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Release|iPhone.Build.0 = Release|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Release|x64.ActiveCfg = Release|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Release|x64.Build.0 = Release|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Release|x86.ActiveCfg = Release|Any CPU
{2182D09E-594C-472D-BB15-37ECEAA9DD22}.Release|x86.Build.0 = Release|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Ad-Hoc|ARM64.ActiveCfg = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Ad-Hoc|ARM64.Build.0 = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.AppStore|ARM.Build.0 = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.AppStore|ARM64.ActiveCfg = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.AppStore|ARM64.Build.0 = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.AppStore|iPhone.Build.0 = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.AppStore|x64.ActiveCfg = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.AppStore|x64.Build.0 = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.AppStore|x86.ActiveCfg = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.AppStore|x86.Build.0 = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Debug|ARM.ActiveCfg = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Debug|ARM.Build.0 = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Debug|ARM64.Build.0 = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Debug|iPhone.Build.0 = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Debug|x64.ActiveCfg = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Debug|x64.Build.0 = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Debug|x86.ActiveCfg = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Debug|x86.Build.0 = Debug|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Release|Any CPU.Build.0 = Release|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Release|ARM.ActiveCfg = Release|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Release|ARM.Build.0 = Release|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Release|ARM64.ActiveCfg = Release|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Release|ARM64.Build.0 = Release|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Release|iPhone.ActiveCfg = Release|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Release|iPhone.Build.0 = Release|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Release|x64.ActiveCfg = Release|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Release|x64.Build.0 = Release|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Release|x86.ActiveCfg = Release|Any CPU
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
......@@ -1602,6 +1718,8 @@ Global
{B6182E93-C6B0-4494-840E-BB045933857C} = {799A84A2-2161-4676-878B-5610E3586137}
{65A8ECFD-4D73-48A3-A05E-3D8807FEB0C2} = {799A84A2-2161-4676-878B-5610E3586137}
{B0796D95-FA72-4154-9668-1F939BF03816} = {799A84A2-2161-4676-878B-5610E3586137}
{2182D09E-594C-472D-BB15-37ECEAA9DD22} = {799A84A2-2161-4676-878B-5610E3586137}
{BF015FF6-DF34-4DDC-89B2-8D7DBF940383} = {799A84A2-2161-4676-878B-5610E3586137}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {AB1424F9-871B-444A-9278-18227672889C}
......
......@@ -2,31 +2,40 @@
<PropertyGroup>
<Title>LibVLCSharp</Title>
<Summary>The official .NET wrapper around LibVLC.</Summary>
<Description>
LibVLCSharp is a cross-platform audio and video API for .NET platforms based on VideoLAN's LibVLC Library.
It provides a comprehensive multimedia API that can be used across mobile, server and desktop to render video and output audio. Mono, .NET Framework and .NET Core runtimes are supported.
This package contains the core features of LibVLCSharp (libvlc loading and initialization, .NET-friendly classes to ease the use of libvlc...). All other `LibVLCSharp.*` packages depend on this one.
<Description>LibVLCSharp is a cross-platform audio and video API for .NET platforms based on VideoLAN's LibVLC Library. It provides a comprehensive multimedia API that can be used across mobile, server and desktop to render video and output audio. Mono, .NET Framework and .NET Core runtimes are supported.
This package also contains the views for the following platforms:
This package contains the core features of LibVLCSharp (libvlc loading and initialization, .NET-friendly classes to ease the use of libvlc...). All other `LibVLCSharp.*` packages depend on this one.
Features:
- Plays all formats
- Network browsing for distant filesystems (SMB, FTP, SFTP, NFS...).
- HDMI pass-through for Audio HD codecs, like E-AC3, TrueHD or DTS-HD.
- Stream to distant renderers, like Chromecast.
- 360 video and 3D audio playback with viewpoint change.
- Support for Ambisonics audio and more than 8 audio channels.
- Subtitles size modification live.
- Hardware and software decoding on all platforms.
- DVD playback and menu navigation.
- Equalizer support.
- Android
- iOS
- Mac
- tvOS
- UWP
This package also contains the views for the following platforms:
libvlc needs to be installed separately. See VideoLAN.LibVLC.* packages.
</Description>
- Android
- iOS
- Mac
- tvOS
- UWP
If you need Xamarin.Forms support, see LibVLCSharp.Forms.
LibVLC needs to be installed separately, see VideoLAN.LibVLC.* packages.</Description>
<TargetFrameworks>netstandard2.0;netstandard1.1;net40;net471</TargetFrameworks>
<TargetFrameworks Condition="!$([MSBuild]::IsOsPlatform('Linux'))">$(TargetFrameworks);MonoAndroid81;Xamarin.iOS10;Xamarin.Mac20;Xamarin.TVOS10</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOsPlatform('Windows'))">$(TargetFrameworks);uap10.0</TargetFrameworks>
<TargetFrameworks Condition="!$([MSBuild]::IsOsPlatform('Linux'))">$(TargetFrameworks);Xamarin.iOS10;Xamarin.Mac20;Xamarin.TVOS10</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOsPlatform('Windows'))">$(TargetFrameworks);uap10.0;uap10.0.16299</TargetFrameworks>
<TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);IncludeAWindow</TargetsForTfmSpecificBuildOutput>
<RootNamespace>LibVLCSharp</RootNamespace>
<NeutralLanguage>en</NeutralLanguage>
<LangVersion>7.3</LangVersion>
<PackageVersion>0.8.1</PackageVersion>
<Version>4.0-alpha</Version>
<PackageId>LibVLCSharp</PackageId>
<Authors>VideoLAN</Authors>
<Owners>VideoLAN</Owners>
......
using System;
using LibVLCSharp.Shared.Helpers;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
......@@ -37,6 +38,9 @@ namespace LibVLCSharp.Shared
[DllImport(Constants.LibraryName, EntryPoint = "JNI_OnLoad")]
internal static extern int JniOnLoad(IntPtr javaVm, IntPtr reserved = default(IntPtr));
#endif
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_get_version")]
internal static extern IntPtr LibVLCVersion();
}
#if NET || NETSTANDARD
......@@ -50,6 +54,8 @@ namespace LibVLCSharp.Shared
/// Load the native libvlc library (if necessary, depending on platform)
/// <para/> Ensure that you installed the VideoLAN.LibVLC.[YourPlatform] package in your target project
/// <para/> This will throw a <see cref="VLCException"/> if the native libvlc libraries cannot be found or loaded.
/// <para/> It may also throw a <see cref="VLCException"/> if the LibVLC and LibVLCSharp major versions do not match.
/// See https://code.videolan.org/videolan/LibVLCSharp/blob/master/VERSIONING.md for more info about the versioning strategy.
/// </summary>
/// <param name="libvlcDirectoryPath">The path to the directory that contains libvlc and libvlccore
/// No need to specify unless running netstandard 1.1, or using custom location for libvlc
......@@ -63,9 +69,26 @@ namespace LibVLCSharp.Shared
InitializeUWP();
#elif NET || NETSTANDARD
InitializeDesktop(libvlcDirectoryPath);
#endif
#if !UWP10_0 && !NETSTANDARD1_1
EnsureVersionsMatch();
#endif
}
#if !UWP10_0 && !NETSTANDARD1_1
/// <summary>
/// Checks whether the major version of LibVLC and LibVLCSharp match <para/>
/// Throws an NotSupportedException if the major versions mismatch
/// </summary>
static void EnsureVersionsMatch()
{
var libvlcMajorVersion = int.Parse(Native.LibVLCVersion().FromUtf8().Split('.').First());
var libvlcsharpMajorVersion = Assembly.GetExecutingAssembly().GetName().Version.Major;
if(libvlcMajorVersion != libvlcsharpMajorVersion)
throw new VLCException($"Version mismatch between LibVLC {libvlcMajorVersion} and LibVLCSharp {libvlcsharpMajorVersion}. " +
$"They must share the same major version number");
}
#endif
#if ANDROID
static void InitializeAndroid()
{
......
......@@ -205,24 +205,24 @@ namespace LibVLCSharp.Shared
internal DialogCallbacks(DisplayErrorCallback displayError, DisplayLoginCallback displayLogin, DisplayQuestionCallback displayQuestion,
DisplayProgressCallback displayProgress, CancelCallback cancel, UpdateProgressCallback updateProgress)
{
DisplayError = displayError;
DisplayLogin = displayLogin;
DisplayQuestion = displayQuestion;
DisplayProgress = displayProgress;
Cancel = cancel;
UpdateProgress = updateProgress;
DisplayError = Marshal.GetFunctionPointerForDelegate(displayError);
DisplayLogin = Marshal.GetFunctionPointerForDelegate(displayLogin);
DisplayQuestion = Marshal.GetFunctionPointerForDelegate(displayQuestion);
DisplayProgress = Marshal.GetFunctionPointerForDelegate(displayProgress);
Cancel = Marshal.GetFunctionPointerForDelegate(cancel);
UpdateProgress = Marshal.GetFunctionPointerForDelegate(updateProgress);
}
internal readonly DisplayErrorCallback DisplayError;
internal readonly IntPtr DisplayError;
internal readonly DisplayLoginCallback DisplayLogin;
internal readonly IntPtr DisplayLogin;
internal readonly DisplayQuestionCallback DisplayQuestion;
internal readonly IntPtr DisplayQuestion;
internal readonly DisplayProgressCallback DisplayProgress;
internal readonly IntPtr DisplayProgress;
internal readonly CancelCallback Cancel;
internal readonly IntPtr Cancel;
internal readonly UpdateProgressCallback UpdateProgress;
internal readonly IntPtr UpdateProgress;
}
}
\ No newline at end of file
......@@ -29,8 +29,6 @@ namespace LibVLCSharp.Shared
#if NET || NETSTANDARD
IntPtr _logFileHandle;
#endif
IntPtr _dialogCbsPtr;
public override int GetHashCode()
{
return NativeReference.GetHashCode();
......@@ -110,7 +108,7 @@ namespace LibVLCSharp.Shared
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_dialog_set_callbacks")]
internal static extern void LibVLCDialogSetCallbacks(IntPtr libVLC, IntPtr callbacks, IntPtr data);
internal static extern void LibVLCDialogSetCallbacks(IntPtr libVLC, DialogCallbacks callbacks, IntPtr data);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_renderer_discoverer_list_get")]
......@@ -301,18 +299,7 @@ namespace LibVLCSharp.Shared
idUtf8, versionUtf8, iconUtf8);
}
/// <summary>
/// Unset dialog callbacks if previously set
/// </summary>
public void UnsetDialogHandlers()
{
if (DialogHandlersSet)
{
Marshal.FreeHGlobal(_dialogCbsPtr);
_dialogCbsPtr = IntPtr.Zero;
Native.LibVLCDialogSetCallbacks(NativeReference, IntPtr.Zero, IntPtr.Zero);
}
}
#if NET || NETSTANDARD
/// <summary>
......@@ -437,7 +424,7 @@ namespace LibVLCSharp.Shared
m => m.Build(),
Native.LibVLCMediaDiscovererListRelease);
readonly Dictionary<IntPtr, CancellationTokenSource> _cts = new Dictionary<IntPtr, CancellationTokenSource>();
#region DialogManagement
/// <summary>
/// Register callbacks in order to handle VLC dialogs.
......@@ -453,59 +440,107 @@ namespace LibVLCSharp.Shared
public void SetDialogHandlers(DisplayError error, DisplayLogin login, DisplayQuestion question,
DisplayProgress displayProgress, UpdateProgress updateProgress)
{
if (error == null) throw new ArgumentNullException(nameof(error));
if (login == null) throw new ArgumentNullException(nameof(login));
if (question == null) throw new ArgumentNullException(nameof(question));
if (displayProgress == null) throw new ArgumentNullException(nameof(displayProgress));
if (updateProgress == null) throw new ArgumentNullException(nameof(updateProgress));
var dialogCbs = new DialogCallbacks(
displayError: (data, title, text) => error(title, text),
displayLogin: (data, id, title, text, username, store) =>
{
var cts = new CancellationTokenSource();
var dlg = new Dialog(new DialogId(id));
_cts[id] = cts;
login(dlg, title, text, username, store, cts.Token);
},
displayQuestion: (data, id, title, text, type, cancelText, firstActionText, secondActionText) =>
{
var cts = new CancellationTokenSource();
var dlg = new Dialog(new DialogId(id));
_cts[id] = cts;
question(dlg, title, text, type, cancelText, firstActionText, secondActionText, cts.Token);
},
displayProgress: (data, id, title, text, indeterminate, position, cancelText) =>
{
var cts = new CancellationTokenSource();
var dlg = new Dialog(new DialogId(id));
_cts[id] = cts;
displayProgress(dlg, title, text, indeterminate, position, cancelText, cts.Token);
},
cancel: (data, id) =>
{
if (_cts.TryGetValue(id, out var token))
{
token.Cancel();
_cts.Remove(id);
}
},
updateProgress: (data, id, position, text) =>
{
var dlg = new Dialog(new DialogId(id));
updateProgress(dlg, position, text);
});
_dialogCbsPtr = Marshal.AllocHGlobal(MarshalUtils.SizeOf(dialogCbs));
Marshal.StructureToPtr(dialogCbs, _dialogCbsPtr, true);
Native.LibVLCDialogSetCallbacks(NativeReference, _dialogCbsPtr, IntPtr.Zero);
_error = error ?? throw new ArgumentNullException(nameof(error));
_login = login ?? throw new ArgumentNullException(nameof(login));
_question = question ?? throw new ArgumentNullException(nameof(question));
_displayProgress = displayProgress ?? throw new ArgumentNullException(nameof(displayProgress));
_updateProgress = updateProgress ?? throw new ArgumentNullException(nameof(updateProgress));
_dialogCbs = new DialogCallbacks(Error, Login, Question, DisplayProgress, Cancel, UpdateProgress);
Native.LibVLCDialogSetCallbacks(NativeReference, _dialogCbs, IntPtr.Zero);
}
/// <summary>
/// Unset dialog callbacks if previously set
/// </summary>
public void UnsetDialogHandlers()
{
if (DialogHandlersSet)
{
_dialogCbs = default;
Native.LibVLCDialogSetCallbacks(NativeReference, _dialogCbs, IntPtr.Zero);
_error = null;
_login = null;
_question = null;
_displayProgress = null;
_updateProgress = null;
}
}
/// <summary>
/// True if dialog handlers are set
/// </summary>
public bool DialogHandlersSet => _dialogCbsPtr != IntPtr.Zero;
public bool DialogHandlersSet => _dialogCbs.DisplayLogin != IntPtr.Zero;
DialogCallbacks _dialogCbs;
static DisplayError _error;
static DisplayLogin _login;
static DisplayQuestion _question;
static DisplayProgress _displayProgress;
static UpdateProgress _updateProgress;
static readonly Dictionary<IntPtr, CancellationTokenSource> _cts = new Dictionary<IntPtr, CancellationTokenSource>();
[MonoPInvokeCallback(typeof(DisplayErrorCallback))]
static void Error(IntPtr data, string title, string text)
{
_error?.Invoke(title, text);
}
[MonoPInvokeCallback(typeof(DisplayLoginCallback))]
static void Login(IntPtr data, IntPtr dialogId, string title, string text, string defaultUsername, bool askStore)
{
if (_login == null) return;
var cts = new CancellationTokenSource();
var dlg = new Dialog(new DialogId(dialogId));
_cts[dialogId] = cts;
_login(dlg, title, text, defaultUsername, askStore, cts.Token);
}
[MonoPInvokeCallback(typeof(DisplayQuestionCallback))]
static void Question(IntPtr data, IntPtr dialogId, string title, string text, DialogQuestionType type,
string cancelText, string firstActionText, string secondActionText)
{
if (_question == null) return;
var cts = new CancellationTokenSource();
var dlg = new Dialog(new DialogId(dialogId));
_cts[dialogId] = cts;
_question(dlg, title, text, type, cancelText, firstActionText, secondActionText, cts.Token);
}
[MonoPInvokeCallback(typeof(DisplayProgressCallback))]
static void DisplayProgress(IntPtr data, IntPtr dialogId, string title, string text, bool indeterminate, float position, string cancelText)
{
if (_displayProgress == null) return;
var cts = new CancellationTokenSource();
var dlg = new Dialog(new DialogId(dialogId));
_cts[dialogId] = cts;
_displayProgress(dlg, title, text, indeterminate, position, cancelText, cts.Token);
}
[MonoPInvokeCallback(typeof(CancelCallback))]
static void Cancel(IntPtr data, IntPtr dialogId)
{
if (_cts.TryGetValue(dialogId, out var token))
{
token.Cancel();
_cts.Remove(dialogId);
}
}
[MonoPInvokeCallback(typeof(UpdateProgressCallback))]
static void UpdateProgress(IntPtr data, IntPtr dialogId, float position, string text)
{
if (_updateProgress == null) return;
var dlg = new Dialog(new DialogId(dialogId));
_updateProgress(dlg, position, text);
}
#endregion
/// <summary>
/// List of available renderers used to create RendererDiscoverer objects
/// Note: LibVLC 3.0.0 and later
......
......@@ -307,7 +307,10 @@ namespace LibVLCSharp.Shared
{
if (mediaConfiguration == null) throw new ArgumentNullException(nameof(mediaConfiguration));
AddOption(mediaConfiguration.Build());
foreach(var option in mediaConfiguration.Build())
{
AddOption(option);
}
}
/// <summary>Add an option to the media with configurable flags.</summary>
......@@ -1082,23 +1085,5 @@ namespace LibVLCSharp.Shared
Playlist = 5
}
#endregion
/// <summary>
/// Small configuration helper
/// </summary>
public class MediaConfiguration
{
HashSet<string> _options = new HashSet<string>();
public MediaConfiguration EnableHardwareDecoding()
{
#if ANDROID
_options.Add(":codec=mediacodec_ndk");
#endif
return this;
}
public string Build() => string.Join(",", _options);
}
}
#endregion
}
\ No newline at end of file
using System.Collections.Generic;
using System.Linq;
namespace LibVLCSharp.Shared
{
/// <summary>
/// Configuration helper designed to be used for advanced libvlc configuration
/// <para/> More info at https://wiki.videolan.org/VLC_command-line_help/
/// </summary>
public class MediaConfiguration
{
readonly Dictionary<string, string> _options = new Dictionary<string, string>
{
{ nameof(EnableHardwareDecoding), string.Empty },
{ nameof(FileCaching), string.Empty },
{ nameof(NetworkCaching), string.Empty },
};
bool _enableHardwareDecoding;
/// <summary>
/// Enable/disable hardware decoding (crossplatform).
/// </summary>
public bool EnableHardwareDecoding
{
get => _enableHardwareDecoding;
set
{
_enableHardwareDecoding = value;
_options[nameof(EnableHardwareDecoding)] = HardwareDecodingOptionString(_enableHardwareDecoding);
}
}
int _fileCaching;
/// <summary>
/// Caching value for local files, in milliseconds [0 .. 60000ms]
/// </summary>
public int FileCaching
{
get => _fileCaching;
set
{
_fileCaching = value;
_options[nameof(FileCaching)] = _fileCaching.ToString();
}
}
int _networkCaching;
/// <summary>
/// Caching value for network resources, in milliseconds [0 .. 60000ms]
/// </summary>
public int NetworkCaching
{
get => _networkCaching;
set
{
_networkCaching = value;
_options[nameof(NetworkCaching)] = _networkCaching.ToString();
}
}
#if ANDROID
const string ENABLE_HW_ANDROID = ":codec=mediacodec_ndk";
const string DISABLE_HW_ANDROID = "";
#endif
const string ENABLE_HW_APPLE = ":videotoolbox";
const string ENABLE_HW_WINDOWS = ":avcodec-hw=d3d11va";
const string DISABLE_HW_APPLE = ":no-videotoolbox";
const string DISABLE_HW_WINDOWS = ":avcodec-hw=none";
private string HardwareDecodingOptionString(bool enable)
{
if(enable)
{
#if ANDROID
return ENABLE_HW_ANDROID;
#elif APPLE
return ENABLE_HW_APPLE;
#else
if (PlatformHelper.IsWindows)
return ENABLE_HW_WINDOWS;
if (PlatformHelper.IsMac)
return ENABLE_HW_APPLE;
return string.Empty;
#endif
}
else
{
#if ANDROID
return DISABLE_HW_ANDROID;
#elif APPLE
return DISABLE_HW_APPLE;
#else
if (PlatformHelper.IsWindows)
return DISABLE_HW_WINDOWS;
if (PlatformHelper.IsMac)
return DISABLE_HW_APPLE;
return string.Empty;
#endif
}
}
/// <summary>
/// Builds the current MediaConfiguration for consumption by libvlc (or storage)
/// </summary>
/// <returns>Configured libvlc options as strings</returns>
public string[] Build() => _options.Values.Where(option => !string.IsNullOrEmpty(option)).ToArray();
}
}
\ No newline at end of file
......@@ -64,7 +64,7 @@ namespace LibVLCSharp.Shared
EntryPoint = "libvlc_media_player_stop")]
internal static extern void LibVLCMediaPlayerStop(IntPtr mediaPlayer);
#if COCOA || NET || NETSTANDARD
#if APPLE || NET || NETSTANDARD
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_set_nsobject")]
internal static extern void LibVLCMediaPlayerSetNsobject(IntPtr mediaPlayer, IntPtr drawable);
......@@ -602,6 +602,11 @@ namespace LibVLCSharp.Shared
[DllImport(Constants.UnityPlugin, EntryPoint = "getVideoFrameVLC")]
internal static extern IntPtr GetFrame(IntPtr mediaPlayer, out bool updated);
#endif
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_direct3d_set_callbacks")]
internal static extern bool LibVLCVideoDirect3DSetCallbacks(IntPtr mediaplayer, Direct3DEngine engine,
IntPtr setupCb, IntPtr cleanupCb, IntPtr resizeCb, IntPtr updateOutputCb,
IntPtr swapCb, IntPtr startEndRenderingCb, IntPtr selectPlaneCb, IntPtr opaque);
}
MediaPlayerEventManager _eventManager;
......@@ -664,7 +669,11 @@ namespace LibVLCSharp.Shared
/// If playback was already started, this method has no effect
/// </summary>
/// <returns>true if successful</returns>
public bool Play() => Native.LibVLCMediaPlayerPlay(NativeReference) == 0;
public bool Play()
{
Media?.AddOption(Configuration);
return Native.LibVLCMediaPlayerPlay(NativeReference) == 0;
}
/// <summary>
/// Set media and start playback
......@@ -697,7 +706,7 @@ namespace LibVLCSharp.Shared
/// </summary>
public void Stop() => Native.LibVLCMediaPlayerStop(NativeReference);
#if COCOA || NET || NETSTANDARD
#if APPLE || NET || NETSTANDARD
/// <summary>
/// Get the NSView handler previously set
/// return the NSView handler or 0 if none where set
......@@ -1648,6 +1657,61 @@ namespace LibVLCSharp.Shared
public bool SetRenderer(RendererItem rendererItem) =>
Native.LibVLCMediaPlayerSetRenderer(NativeReference, rendererItem.NativeReference) == 0;
/// <summary>
/// Set callbacks and data to render decoded video to a custom Direct3D output <para/>
/// warning: VLC will perform video rendering in its own thread and at its own rate,
/// You need to provide your own synchronisation mechanism.
/// <para/>LibVLC 4.0.0 or later
/// </summary>
/// <param name="engine">the GPU engine to use</param>
/// <param name="setupCb">callback to setup and return the device to use (cannot be NULL)</param>
/// <param name="cleanupCb">callback to cleanup the device given by the <see cref="LibVLCD3DSetupCb"/> callback</param>
/// <param name="updateOutputCb">callback to notify of the source format and get the rendering format used by the host (cannot be NULL)</param>
/// <param name="swapCb">callback to tell the host it should display the rendered picture (cannot be NULL)</param>
/// <param name="startEndRenderingCb">callback to tell the host the rendering is starting/ended (cannot be NULL)</param>
/// <param name="selectPlaneCb">callback to select different D3D11 rendering targets</param>
/// <param name="opaque">private pointer passed to the <see cref="LibVLCD3DCleanupCb"/> callback</param>
/// <returns>true Direct3D selected and callbacks set, false otherwise</returns>
public bool SetDirect3DCallbacks(Direct3DEngine engine, LibVLCD3DSetupCb setupCb, LibVLCD3DCleanupCb cleanupCb, LibVLCD3DResize resizeCb,
LibVLCD3DUpdateOutputCb updateOutputCb, LibVLCSwapCb swapCb, LibVLCD3DStartEndRenderingCb startEndRenderingCb,
LibVLCD3DSelectPlaneCb selectPlaneCb, IntPtr opaque)
{
setup = setupCb;
cleanup = cleanupCb;
resize = resizeCb;
updateOutput = updateOutputCb;
swap = swapCb;
startEndRendering = startEndRenderingCb;
selectPlane = selectPlaneCb;
var setupPtr = setup == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(setup);
var cleanupPtr = cleanup == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(cleanup);
var resizePtr = resize == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(resize);
var updateOutputPtr = updateOutput == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(updateOutput);
var swapPtr = swap == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(swap);
var startEndRenderingPtr = startEndRendering == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(startEndRendering);
var selectPlanePtr = selectPlane == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(selectPlane);
return Native.LibVLCVideoDirect3DSetCallbacks(NativeReference,
engine,
setupPtr,
cleanupPtr,
resizePtr,
updateOutputPtr,
swapPtr,
startEndRenderingPtr,
selectPlanePtr,
opaque);
}
LibVLCD3DSetupCb setup;
LibVLCD3DCleanupCb cleanup;
LibVLCD3DResize resize;
LibVLCD3DUpdateOutputCb updateOutput;
LibVLCSwapCb swap;
LibVLCD3DStartEndRenderingCb startEndRendering;
LibVLCD3DSelectPlaneCb selectPlane;
/// <summary>Gets the media role.
/// <para/> version LibVLC 3.0.0 and later.
/// </summary>
......@@ -1662,6 +1726,35 @@ namespace LibVLCSharp.Shared
/// <summary>Increments the native reference counter for this mediaplayer instance</summary>
internal void Retain() => Native.LibVLCMediaPlayerRetain(NativeReference);
/// <summary>
/// Enable/disable hardware decoding in a crossplatform way.
/// </summary>
public bool EnableHardwareDecoding
{
get => Configuration.EnableHardwareDecoding;
set => Configuration.EnableHardwareDecoding = value;
}
/// <summary>
/// Caching value for local files, in milliseconds [0 .. 60000ms]
/// </summary>
public int FileCaching
{
get => Configuration.FileCaching;
set => Configuration.FileCaching = value;
}
/// <summary>
/// Caching value for network resources, in milliseconds [0 .. 60000ms]
/// </summary>
public int NetworkCaching
{
get => Configuration.NetworkCaching;
set => Configuration.NetworkCaching = value;
}
MediaConfiguration Configuration = new MediaConfiguration();
#if UNITY_ANDROID
/// <summary>
/// Retrieve a video frame from the Unity plugin.
......@@ -1676,7 +1769,7 @@ namespace LibVLCSharp.Shared
}
#endif
#region Callbacks
#region Callbacks
/// <summary>
/// <para>A LibVLC media player plays one media (usually in a custom drawable).</para>
......@@ -1861,8 +1954,132 @@ namespace LibVLCSharp.Shared
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void LibVLCVolumeCb(IntPtr data, float volume, [MarshalAs(UnmanagedType.I1)] bool mute);
#endregion
/// <summary>
/// Setup the rendering environment. <para/>
/// For <see cref="Direct3DEngine.D3D9"/>, the output must be a IDirect3D9*.
/// A reference to this object is held until <see cref="LibVLCD3DSetupCb"/> is called.
/// the device must be created with D3DPRESENT_PARAMETERS.hDeviceWindow set to 0.
/// <para/>
/// For <see cref="Direct3DEngine.D3D11"/>, the output must be a ID3D11DeviceContext*.
/// A reference to this object is held until <see cref="LibVLCD3DSetupCb"/> is called.
/// The ID3D11Device used to create ID3D11DeviceContext must have multithreading enabled.
/// <para/>
/// version LibVLC 4.0.0 or later
/// </summary>
/// <param name="opaque">private pointer passed to the <see cref="SetDirect3DCallbacks"/>
/// on input. The callback can change this value on output to be passed to all the other callbacks set on <see cref="SetDirect3DCallbacks"/>. [IN/OUT]
/// </param>
/// <param name="config">requested <see cref="D3DConfig"/> of the video device</param>
/// <param name="setup"><see cref="D3DSetup"/> to fill</param>
/// <returns>true on success</returns>
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
public delegate bool LibVLCD3DSetupCb(IntPtr opaque, IntPtr config, IntPtr setup);
/// <summary>
/// Cleanup the rendering environment initialized during <see cref="LibVLCD3DSetupCb"/>.
/// <para/>
/// version LibVLC 4.0.0 or later
/// </summary>
/// <param name="opaque">private pointer set on the opaque parameter of <see cref="LibVLCD3DSetupCb"/> [IN]</param>
/// <returns></returns>
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void LibVLCD3DCleanupCb(IntPtr opaque);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void ResizeReport(IntPtr report_opaque, uint width, uint height);
/// <summary>
/// Set the callback to call when the host app resizes the rendering area.
/// <para/>
/// This allows text rendering and aspect ratio to be handled properly when the host
/// rendering size changes.
/// <para/>
/// It may be called before the <see cref="LibVLCD3DSetupCb"/> callback.
/// <para/>
/// version LibVLC 4.0.0 or later
/// </summary>
/// <param name="opaque">private pointer set on the opaque parameter of <see cref="LibVLCD3DSetupCb"/></param>
/// <param name="report_size_change">callback which must be called when the host size changes.
/// <para/>The callback is valid until another call to <see cref="LibVLCD3DResize"/>
/// is done. This may be called from any thread.</param>
/// <param name="report_opaque">private pointer to pass to the <see cref="ResizeReport"/> callback</param>
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void LibVLCD3DResize(IntPtr opaque, ResizeReport report_size_change, IntPtr report_opaque);
/// <summary>
/// Update the rendering output setup. <para/>
/// Note: the configuration device for Direct3D9 is the IDirect3DDevice9 that VLC
/// uses to render. The host must set a Render target and call Present()
/// when it needs the drawing from VLC to be done.This object is not valid
/// anymore after Cleanup is called. <para/>
/// Tone mapping, range and color conversion will be done depending on the values set in the output structure.
/// </summary>
/// <param name="opaque">private pointer passed to the <see cref="SetDirect3DCallbacks"/>[IN]</param>
/// <param name="config">configuration of the video that will be rendered [IN]</param>
/// <param name="output">output configuration describing with how the rendering is setup [OUT]</param>
/// <returns>true on success</returns>
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
public delegate bool LibVLCD3DUpdateOutputCb(IntPtr opaque, IntPtr config, IntPtr output);
/// <summary>
/// Callback prototype called after performing drawing calls.