...
 
Commits (26)
......@@ -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.
## 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).
......@@ -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).
......@@ -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('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>3.0.2</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
......@@ -44,8 +44,19 @@ namespace LibVLCSharp.Shared.Helpers
public static extern void LibVLCFree(IntPtr ptr);
const string Write = "w";
}
#if !NETSTANDARD1_1 && !UAP
[DllImport(Constants.libSystem)]
public static extern int vsprintf(IntPtr buffer, IntPtr format, IntPtr argptr);
#endif
}
#if !NETSTANDARD1_1 && !UAP
internal static int vsprintf(IntPtr buffer, IntPtr format, IntPtr argptr)
{
return Native.vsprintf(buffer, format, argptr);
}
#endif
/// <summary>
/// Helper for libvlc_new
/// </summary>
......
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using LibVLCSharp.Shared.Helpers;
using LibVLCSharp.Shared.Structures;
......@@ -26,11 +28,18 @@ namespace LibVLCSharp.Shared
if (obj.GetType() != this.GetType()) return false;
return Equals((LibVLC) obj);
}
#if NET || NETSTANDARD
IntPtr _logFileHandle;
#endif
IntPtr _dialogCbsPtr;
LogCallback _logCallback;
readonly object _logLock = new object();
/// <summary>
/// The real log event handlers.
/// </summary>
static EventHandler<LogEventArgs> _log;
/// <summary>
/// A boolean to make sure that we are calling SetLog only once
/// </summary>
bool _logAttached;
public override int GetHashCode()
{
return NativeReference.GetHashCode();
......@@ -64,6 +73,10 @@ namespace LibVLCSharp.Shared
EntryPoint = "libvlc_set_app_id")]
internal static extern void LibVLCSetAppId(IntPtr libVLC, IntPtr id, IntPtr version, IntPtr icon);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_log_unset")]
internal static extern void LibVLCLogUnset(IntPtr libVLC);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_log_set_file")]
internal static extern void LibVLCLogSetFile(IntPtr libVLC, IntPtr stream);
......@@ -72,6 +85,10 @@ namespace LibVLCSharp.Shared
CharSet = CharSet.Ansi, EntryPoint = "libvlc_log_get_context")]
internal static extern void LibVLCLogGetContext(IntPtr ctx, out IntPtr module, out IntPtr file, out UIntPtr line);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_log_set")]
internal static extern void LibVLCLogSet(IntPtr libVLC, LogCallback cb, IntPtr data);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_module_description_list_release")]
internal static extern void LibVLCModuleDescriptionListRelease(IntPtr moduleDescriptionList);
......@@ -110,7 +127,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,54 +318,50 @@ 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>
/// Close log file handle
/// </summary>
/// <returns>true if no file to close or close operation successful, false otherwise</returns>
public bool CloseLogFile()
public void SetLog(LogCallback cb)
{
if (_logFileHandle == IntPtr.Zero) return true;
if (cb == null) throw new ArgumentException(nameof(cb));
return MarshalUtils.Close(_logFileHandle);
_logCallback = cb;
Native.LibVLCLogSet(NativeReference, cb, IntPtr.Zero);
}
/// <summary>Sets up logging to a file.
/// Watch out: Overwrite contents if file exists!
/// Potentially throws a VLCException if FILE * cannot be obtained
/// </summary>
/// <para>FILE pointer opened for writing</para>
/// <para>(the FILE pointer must remain valid until libvlc_log_unset())</para>
/// <param name="filename">open/create file with Write access. If existing, resets content.</param>
/// <remarks>LibVLC 2.1.0 or later</remarks>
public void SetLogFile(string filename)
{
if (string.IsNullOrEmpty(filename)) throw new NullReferenceException(nameof(filename));
//static void Logcb(IntPtr data, LogLevel logLevel, IntPtr logContext, IntPtr format, IntPtr args)
//{
_logFileHandle = NativeFilePtr(filename);
//}
Native.LibVLCLogSetFile(NativeReference, _logFileHandle);
}
#if !NETSTANDARD1_1 && !NET40
IntPtr NativeFilePtr(string filename)
/// <summary>
/// The event that is triggered when a log is emitted from libVLC.
/// Listening to this event will discard the default logger in libvlc.
/// </summary>
public event EventHandler<LogEventArgs> Log
{
var result = MarshalUtils.Open(filename, out var filePtr);
if (!result)
throw new VLCException("Could not get FILE * for log_set_file");
return filePtr;
add
{
lock (_logLock)
{
_log += value;
if (!_logAttached)
{
SetLog(OnLogInternal);
_logAttached = true;
}
}
}
remove
{
lock (_logLock)
{
_log -= value;
}
}
}
#endif
/// <summary>Returns a list of audio filters that are available.</summary>
......@@ -437,7 +450,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 +466,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);
});
_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);
}
_dialogCbsPtr = Marshal.AllocHGlobal(MarshalUtils.SizeOf(dialogCbs));
Marshal.StructureToPtr(dialogCbs, _dialogCbsPtr, true);
Native.LibVLCDialogSetCallbacks(NativeReference, _dialogCbsPtr, 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
......@@ -516,6 +577,84 @@ namespace LibVLCSharp.Shared
m => m.Build(),
Native.LibVLCRendererDiscovererReleaseList);
#if !NETSTANDARD1_1 && !NET40
/// <summary>
/// Code taken from Vlc.DotNet
/// </summary>
/// <param name="data"></param>
/// <param name="level"></param>
/// <param name="ctx"></param>
/// <param name="format"></param>
/// <param name="args"></param>
[MonoPInvokeCallback(typeof(LogCallback))]
static void OnLogInternal(IntPtr data, LogLevel level, IntPtr ctx, IntPtr format, IntPtr args)
{
if (_log == null) return;
IntPtr buffer = Marshal.AllocHGlobal(2048);
var count = MarshalUtils.vsprintf(buffer, format, args);
if(count > -1)
{
//var message = Marshal.PtrToStringAnsi(buffer, count);
var message = buffer.FromUtf8();
// Marshal.FreeHGlobal(buffer);
// GetLogContext(ctx, out var module, out var file, out var line);
Task.Run(() => _log?.Invoke(null, new LogEventArgs(level, message, null, null, null)));
//Task.Run(() => _log?.Invoke(NativeReference, new LogEventArgs(level, message, module, file, line)));
}
// Original source for va_list handling: https://stackoverflow.com/a/37629480/2663813
//var byteLength = MarshalUtils.Vscprintf(format, args) + 1;
//var utf8Buffer = Marshal.AllocHGlobal(byteLength);
//string formattedDecodedMessage;
//try
//{
// MarshalUtils.Vsprintf(utf8Buffer, format, args);
// formattedDecodedMessage = utf8Buffer.FromUtf8();
//}
//finally
//{
// Marshal.FreeHGlobal(utf8Buffer);
//}
// Do the notification on another thread, so that VLC is not interrupted by the logging
#if NET40
//Task.Factory.StartNew(() => _log?.Invoke(NativeReference, new LogEventArgs(level, formattedDecodedMessage, module, file, line)));
#else
//Task.Run(() => _log?.Invoke(NativeReference, new LogEventArgs(level, formattedDecodedMessage, module, file, line)));
#endif
}
#endif
/// <summary>
/// Gets log message debug infos.
///
/// This function retrieves self-debug information about a log message:
/// - the name of the VLC module emitting the message,
/// - the name of the source code module (i.e.file) and
/// - the line number within the source code module.
///
/// The returned module name and file name will be NULL if unknown.
/// The returned line number will similarly be zero if unknown.
/// </summary>
/// <param name="logContext">The log message context (as passed to the <see cref="LogCallback"/>)</param>
/// <param name="module">The module name storage.</param>
/// <param name="file">The source code file name storage.</param>
/// <param name="line">The source code file line number storage.</param>
void GetLogContext(IntPtr logContext, out string module, out string file, out uint? line)
{
Native.LibVLCLogGetContext(logContext, out var modulePtr, out var filePtr, out var linePtr);
line = linePtr == UIntPtr.Zero ? null : (uint?)linePtr.ToUInt32();
module = modulePtr.FromUtf8();
file = filePtr.FromUtf8();
}
/// <summary>Increments the native reference counter for this libvlc instance</summary>
internal void Retain() => Native.LibVLCRetain(NativeReference);
......@@ -570,5 +709,9 @@ namespace LibVLCSharp.Shared
/// </summary>
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void ExitCallback();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void LogCallback(IntPtr data, LogLevel logLevel, IntPtr logContext, IntPtr format, IntPtr args);
#endregion
}
\ No newline at end of file
......@@ -307,7 +307,11 @@ namespace LibVLCSharp.Shared
{
if (mediaConfiguration == null) throw new ArgumentNullException(nameof(mediaConfiguration));
AddOption(mediaConfiguration.Build());
foreach(var option in mediaConfiguration.Build())
{
if(!string.IsNullOrWhiteSpace(option))
AddOption(option);
}
}
/// <summary>Add an option to the media with configurable flags.</summary>
......@@ -1082,23 +1086,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 in a crossplatform way.
/// </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;
#endif
if (PlatformHelper.IsWindows)
return ENABLE_HW_WINDOWS;
if (PlatformHelper.IsMac)
return ENABLE_HW_APPLE;
return string.Empty;
}
else
{
#if ANDROID
return DISABLE_HW_ANDROID;
#elif APPLE
return DISABLE_HW_APPLE;
#endif
if (PlatformHelper.IsWindows)
return DISABLE_HW_WINDOWS;
if (PlatformHelper.IsMac)
return DISABLE_HW_APPLE;
return string.Empty;
}
}
/// <summary>
/// Builds the current MediaConfiguration for consumption by libvlc (or storage)
/// </summary>
/// <returns></returns>
public string[] Build() => _options.Values.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);
......@@ -664,7 +664,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 +701,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
......@@ -1662,6 +1666,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 +1709,7 @@ namespace LibVLCSharp.Shared
}
#endif
#region Callbacks
#region Callbacks
/// <summary>
/// <para>A LibVLC media player plays one media (usually in a custom drawable).</para>
......@@ -1879,7 +1912,8 @@ namespace LibVLCSharp.Shared
}
}
#region events
#region events
public event EventHandler<MediaPlayerMediaChangedEventArgs> MediaChanged
{
......
LibVLCSharp version 3.0.2
=========================
* Improve nuget docs
* Fix iOS linker issue https://code.videolan.org/videolan/LibVLCSharp/issues/163
LibVLCSharp version 3.0.1
=========================
* Add libvlc/libvlcsharp version check
* Add Xamarin.Forms 4.0 support for LibVLCSharp.Forms
LibVLCSharp version 3.0.0
=========================
* First stable release: https://mfkl.github.io/libvlc/crossplatform/xamarin/forms/release/2019/05/13/LibVLCSharp-goes-stable.html
* VS2019 support
LibVLCSharp version 0.8.1
=========================
* Fix ARM debug support for UWP.
......
......@@ -98,16 +98,17 @@ LibVLC is the actual VLC engine written mostly in C/C++ and compiled for your ta
| Xamarin.Mac | [LibVLCSharp](LibVLCSharp/README.md) | [![LibVLCSharpBadge]][LibVLCSharp] |
| UWP | [LibVLCSharp](LibVLCSharp/README.md) | [![LibVLCSharpBadge]][LibVLCSharp] |
| Xamarin.Forms | [LibVLCSharp.Forms](LibVLCSharp.Forms/README.md)| [![LibVLCSharpFormsBadge]][LibVLCSharpForms] |
| WPF | LibVLCSharp.WPF | [![LibVLCSharpWPFBadge]][LibVLCSharpWPF] |
| Xamarin.Forms.WPF | [LibVLCSharp.Forms.WPF][RLibVLCSharpFormsWPF] | [![LibVLCSharpFormsWPFBadge]][LibVLCSharpFormsWPF]|
| WPF | [LibVLCSharp.WPF](LibVLCSharp.WPF/README.md) | [![LibVLCSharpWPFBadge]][LibVLCSharpWPF] |
| Xamarin.Forms.WPF | [LibVLCSharp.Forms.WPF][RLibVLCSharpFormsWPF] | [![LibVLCSharpFormsWPFBadge]][LibVLCSharpFormsWPF]|
| GTK | [LibVLCSharp.GTK](LibVLCSharp.GTK/README.md) | [![LibVLCSharpGTKBadge]][LibVLCSharpGTK] |
| Xamarin.Forms.GTK | [LibVLCSharp.Forms.GTK][RLibVLCSharpFormsGTK] | [![LibVLCSharpFormsGTKBadge]][LibVLCSharpFormsGTK]|
| Windows Forms | LibVLCSharp.WinForms | [![LibVLCSharpWinFormsBadge]][LibVLCSharpWinForms]|
| Xamarin.Forms.GTK | [LibVLCSharp.Forms.GTK][RLibVLCSharpFormsGTK] | [![LibVLCSharpFormsGTKBadge]][LibVLCSharpFormsGTK]|
| Windows Forms | [LibVLCSharp.WinForms][RLibVLCSharpWinForms] | [![LibVLCSharpWinFormsBadge]][LibVLCSharpWinForms]|
LibVLCSharp is the .NET wrapper that consumes `LibVLC` and allows you to interact with native code from C#/F#.
[RLibVLCSharpFormsWPF]: LibVLCSharp.Forms.Platforms.WPF/README.md
[RLibVLCSharpFormsGTK]: LibVLCSharp.Forms.Platforms.GTK/README.md
[RLibVLCSharpWinForms]: LibVLCSharp.WinForms/README.md
[LibVLCWindowsBadge]: https://img.shields.io/nuget/v/VideoLAN.LibVLC.Windows.svg
[LibVLCWindows]: https://www.nuget.org/packages/VideoLAN.LibVLC.Windows/
......
......@@ -25,6 +25,7 @@ namespace LibVLCSharp.Forms.Sample.Mac
public override void DidFinishLaunching(NSNotification notification)
{
Shared.LibVLCSharpFormsRenderer.Init();
Xamarin.Forms.Forms.Init();
LoadApplication(new App());
base.DidFinishLaunching(notification);
......
......@@ -124,8 +124,8 @@
</PropertyGroup>
<Error Condition="!Exists('..\..\..\packages\Xamarin.Forms.3.2.0.871581\build\netstandard2.0\Xamarin.Forms.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Xamarin.Forms.3.2.0.871581\build\netstandard2.0\Xamarin.Forms.props'))" />
<Error Condition="!Exists('..\..\..\packages\Xamarin.Forms.3.2.0.871581\build\netstandard2.0\Xamarin.Forms.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Xamarin.Forms.3.2.0.871581\build\netstandard2.0\Xamarin.Forms.targets'))" />
<Error Condition="!Exists('..\..\..\packages\VideoLAN.LibVLC.Mac.3.1.2\build\VideoLAN.LibVLC.Mac.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\VideoLAN.LibVLC.Mac.3.1.2\build\VideoLAN.LibVLC.Mac.targets'))" />
<Error Condition="!Exists('..\..\..\packages\VideoLAN.LibVLC.Mac.3.1.3\build\VideoLAN.LibVLC.Mac.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\VideoLAN.LibVLC.Mac.3.1.3\build\VideoLAN.LibVLC.Mac.targets'))" />
</Target>
<Import Project="..\..\..\packages\Xamarin.Forms.3.2.0.871581\build\netstandard2.0\Xamarin.Forms.targets" Condition="Exists('..\..\..\packages\Xamarin.Forms.3.2.0.871581\build\netstandard2.0\Xamarin.Forms.targets')" />
<Import Project="..\..\..\packages\VideoLAN.LibVLC.Mac.3.1.2\build\VideoLAN.LibVLC.Mac.targets" Condition="Exists('..\..\..\packages\VideoLAN.LibVLC.Mac.3.1.2\build\VideoLAN.LibVLC.Mac.targets')" />
<Import Project="..\..\..\packages\VideoLAN.LibVLC.Mac.3.1.3\build\VideoLAN.LibVLC.Mac.targets" Condition="Exists('..\..\..\packages\VideoLAN.LibVLC.Mac.3.1.3\build\VideoLAN.LibVLC.Mac.targets')" />
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="VideoLAN.LibVLC.Mac" version="3.1.2" targetFramework="xamarinmac20" />
<package id="VideoLAN.LibVLC.Mac" version="3.1.3" targetFramework="xamarinmac20" />
<package id="Xamarin.Forms" version="3.2.0.871581" targetFramework="xamarinmac20" />
</packages>
\ No newline at end of file
......@@ -50,6 +50,7 @@
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchDebug>true</MtouchDebug>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<MtouchLink>SdkOnly</MtouchLink>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' ">
<DebugType>none</DebugType>
......@@ -120,7 +121,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="VideoLAN.LibVLC.iOS">
<Version>3.0.0-alpha2</Version>
<Version>3.1.5</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms" Version="3.2.0.871581" />
</ItemGroup>
......
using LibVLCSharp.Shared;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Threading.Tasks;
namespace LibVLCSharp.Forms.Sample
......@@ -35,17 +36,28 @@ namespace LibVLCSharp.Forms.Sample
}
}
private void _libVLC_Log(object sender, LogEventArgs e)
{
Debug.WriteLine($"{e.Level}: {e.Module} -> {e.Message}");
}
private void Initialize()
{
Core.Initialize();
LibVLC = new LibVLC();
LibVLC.Log += _libVLC_Log;
MediaPlayer = new MediaPlayer(LibVLC)
{
Media = new Media(LibVLC,
"http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4",
FromType.FromLocation)
"https://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4",
FromType.FromLocation),
//EnableHardwareDecoding = false
};
MediaPlayer.Media.AddOption(new MediaConfiguration { EnableHardwareDecoding = true });
}
public void OnAppearing()
......
......@@ -29,14 +29,14 @@ namespace LibVLCSharp.Android.Sample
Core.Initialize();
_libVLC = new LibVLC();
_mediaPlayer = new MediaPlayer(_libVLC);
_mediaPlayer = new MediaPlayer(_libVLC)
{
EnableHardwareDecoding = true
};
_videoView = new VideoView(this) { MediaPlayer = _mediaPlayer };
AddContentView(_videoView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent));
var media = new Media(_libVLC, "http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4", FromType.FromLocation);
var configuration = new MediaConfiguration();
configuration.EnableHardwareDecoding();
media.AddOption(configuration);
var media = new Media(_libVLC, "https://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4", FromType.FromLocation);
_videoView.MediaPlayer.Play(media);
}
......
......@@ -7,6 +7,6 @@ let main argv =
Core.Initialize()
let libVLC = new LibVLC()
let mp = new MediaPlayer(libVLC)
mp.Play(new Media(libVLC, "http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4", FromType.FromLocation)) |> ignore
mp.Play(new Media(libVLC, "https://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4", FromType.FromLocation)) |> ignore
let result = Console.ReadKey()
0
\ No newline at end of file
......@@ -28,7 +28,7 @@ namespace LibVLCSharp.GTK.Sample
//Starts playing
using (var media = new Media(libvlc,
"http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4",
"https://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4",