Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GTK# / Xamarin.Forms.Gtk implementations (reloaded) #20

Closed
5 changes: 4 additions & 1 deletion Directory.Build.props
Expand Up @@ -6,7 +6,10 @@
<DefineConstants>$(DefineConstants);NETSTANDARD1_1;NETSTANDARD</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'net40'">
<DefineConstants>$(DefineConstants);NET40</DefineConstants>
<DefineConstants>$(DefineConstants);NET40;NET</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'net471'">
<DefineConstants>$(DefineConstants);NET471;NET</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="$(TargetFramework.StartsWith('Xamarin.iOS'))">
<DefineConstants>$(DefineConstants);MONO;IOS;COCOA</DefineConstants>
Expand Down
@@ -0,0 +1,70 @@
<Project Sdk="Microsoft.NET.Sdk">
<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.

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>
<TargetFramework>net47</TargetFramework>
<RootNamespace>LibVLCSharp.Forms.GTK</RootNamespace>
<PackageVersion>0.0.1</PackageVersion>
<PackageId>LibVLCSharp.Forms.GTK</PackageId>
<Authors>VideoLAN</Authors>
<Owners>VideoLAN</Owners>
<GeneratePackageOnBuild Condition=" '$(Configuration)' == 'Release' ">true</GeneratePackageOnBuild>
<GenerateDocumentationFile Condition=" '$(Configuration)' == 'Release' ">true</GenerateDocumentationFile>
<PackageLicenseExpression>LGPL-2.1-or-later</PackageLicenseExpression>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://code.videolan.org/videolan/LibVLCSharp</RepositoryUrl>
<PackageIconUrl>https://code.videolan.org/videolan/LibVLCSharp/raw/master/Assets/icon.png</PackageIconUrl>
<PackageReleaseNotes>https://code.videolan.org/videolan/LibVLCSharp/blob/master/NEWS</PackageReleaseNotes>
<PackageTags>libvlc;vlc;videolan;native;c/c++;video;audio;player;media;mediaplayer;codec;ffmpeg;xamarin;graphics;ios;android;linux;windows;macos;cross-platform</PackageTags>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Xamarin.Forms.Platform.GTK" Version="3.2.0.871581" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LibVLCSharp.Forms\LibVLCSharp.Forms.csproj" />
<ProjectReference Include="..\LibVLCSharp.GTK\LibVLCSharp.GTK.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="gdk-sharp">
<HintPath Condition="$([MSBuild]::IsOsPlatform('Windows'))">C:\Program Files (x86)\GtkSharp\2.12\lib\gtk-sharp-2.0\gdk-sharp.dll</HintPath>
<HintPath Condition="$([MSBuild]::IsOsPlatform('Linux'))">/usr/lib/cli/gdk-sharp-2.0/gdk-sharp.dll</HintPath>
<HintPath Condition="$([MSBuild]::IsOsPlatform('OSX'))">/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/gtk-sharp-2.0/gdk-sharp.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="glib-sharp">
<Private>False</Private>
<HintPath Condition="$([MSBuild]::IsOsPlatform('Windows'))">C:\Program Files (x86)\GtkSharp\2.12\lib\gtk-sharp-2.0\glib-sharp.dll</HintPath>
<HintPath Condition="$([MSBuild]::IsOsPlatform('Linux'))">/usr/lib/cli/glib-sharp-2.0/glib-sharp.dll</HintPath>
<HintPath Condition="$([MSBuild]::IsOsPlatform('OSX'))">/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/gtk-sharp-2.0/glib-sharp.dll</HintPath>
</Reference>
<Reference Include="gtk-sharp">
<Private>False</Private>
<HintPath Condition="$([MSBuild]::IsOsPlatform('Windows'))">C:\Program Files (x86)\GtkSharp\2.12\lib\gtk-sharp-2.0\gtk-sharp.dll</HintPath>
<HintPath Condition="$([MSBuild]::IsOsPlatform('Linux'))">/usr/lib/cli/gtk-sharp-2.0/gtk-sharp.dll</HintPath>
<HintPath Condition="$([MSBuild]::IsOsPlatform('OSX'))">/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/gtk-sharp-2.0/gtk-sharp.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
51 changes: 51 additions & 0 deletions LibVLCSharp.Forms.Platforms.GTK/VideoViewRenderer.cs
@@ -0,0 +1,51 @@
using LibVLCSharp.Forms.Platforms.GTK;
using LibVLCSharp.Forms.Shared;
using LibVLCSharp.Shared;
using Xamarin.Forms;
using Xamarin.Forms.Platform.GTK;

[assembly: ExportRenderer(typeof(LibVLCSharp.Forms.Shared.VideoView), typeof(VideoViewRenderer))]
namespace LibVLCSharp.Forms.Platforms.GTK
{
public class VideoViewRenderer : ViewRenderer<LibVLCSharp.Forms.Shared.VideoView, LibVLCSharp.GTK.VideoView>
{
LibVLCSharp.GTK.VideoView _videoView;

protected override void OnElementChanged(ElementChangedEventArgs<VideoView> e)
{
base.OnElementChanged(e);

if (Control == null)
{
_videoView = new LibVLCSharp.GTK.VideoView();
SetNativeControl(_videoView);
}

if (e.OldElement != null)
{
e.OldElement.MediaPlayerChanged -= OnMediaPlayerChanged;
}

if (e.NewElement != null)
{
e.NewElement.MediaPlayerChanged += OnMediaPlayerChanged;
}
}

private void OnMediaPlayerChanged(object sender, MediaPlayerChangedEventArgs e)
{
if (Control == null)
{
return;
}
Control.MediaPlayer = e.NewMediaPlayer;
}

protected override void Dispose(bool disposing)
{
base.Dispose(disposing);

_videoView?.Dispose();
}
}
}
5 changes: 3 additions & 2 deletions LibVLCSharp.Forms/LibVLCSharp.Forms.csproj
Expand Up @@ -24,8 +24,9 @@ Features:
- Subtitles size modification live.
- Hardware decoding and display on all platforms.
- DVD playback and menu navigation.
</Description>
<TargetFrameworks>netstandard2.0;MonoAndroid81;Xamarin.iOS10;Xamarin.Mac20</TargetFrameworks>
</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>
Expand Down
66 changes: 66 additions & 0 deletions LibVLCSharp.GTK/LibVLCSharp.GTK.csproj
@@ -0,0 +1,66 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Title>LibVLCSharp.GTK</Title>
<Summary>GTK 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.

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>
<TargetFramework>net47</TargetFramework>
<RootNamespace>LibVLCSharp.GTK</RootNamespace>
<Version>0.0.1</Version>
<PackageId>LibVLCSharp.GTK</PackageId>
<Authors>VideoLAN</Authors>
<Owners>VideoLAN</Owners>
<GeneratePackageOnBuild Condition=" '$(Configuration)' == 'Release' ">true</GeneratePackageOnBuild>
<GenerateDocumentationFile Condition=" '$(Configuration)' == 'Release' ">true</GenerateDocumentationFile>
<UseFullSemVerForNuGet>false</UseFullSemVerForNuGet>
<PackageLicenseExpression>LGPL-2.1-or-later</PackageLicenseExpression>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://code.videolan.org/videolan/LibVLCSharp</RepositoryUrl>
<PackageIconUrl>https://code.videolan.org/videolan/LibVLCSharp/raw/master/Assets/icon.png</PackageIconUrl>
<PackageReleaseNotes>https://code.videolan.org/videolan/LibVLCSharp/blob/master/NEWS</PackageReleaseNotes>
<PackageTags>libvlc;vlc;videolan;native;c/c++;video;audio;player;media;mediaplayer;codec;ffmpeg;xamarin;graphics;ios;android;linux;windows;macos;cross-platform</PackageTags>
</PropertyGroup>
<ItemGroup>
<Reference Include="gdk-sharp">
<HintPath Condition="$([MSBuild]::IsOsPlatform('Windows'))">C:\Program Files (x86)\GtkSharp\2.12\lib\gtk-sharp-2.0\gdk-sharp.dll</HintPath>
<HintPath Condition="$([MSBuild]::IsOsPlatform('Linux'))">/usr/lib/cli/gdk-sharp-2.0/gdk-sharp.dll</HintPath>
<HintPath Condition="$([MSBuild]::IsOsPlatform('OSX'))">/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/gtk-sharp-2.0/gdk-sharp.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="glib-sharp">
<Private>False</Private>
<HintPath Condition="$([MSBuild]::IsOsPlatform('Windows'))">C:\Program Files (x86)\GtkSharp\2.12\lib\gtk-sharp-2.0\glib-sharp.dll</HintPath>
<HintPath Condition="$([MSBuild]::IsOsPlatform('Linux'))">/usr/lib/cli/glib-sharp-2.0/glib-sharp.dll</HintPath>
<HintPath Condition="$([MSBuild]::IsOsPlatform('OSX'))">/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/gtk-sharp-2.0/glib-sharp.dll</HintPath>
</Reference>
<Reference Include="gtk-sharp">
<Private>False</Private>
<HintPath Condition="$([MSBuild]::IsOsPlatform('Windows'))">C:\Program Files (x86)\GtkSharp\2.12\lib\gtk-sharp-2.0\gtk-sharp.dll</HintPath>
<HintPath Condition="$([MSBuild]::IsOsPlatform('Linux'))">/usr/lib/cli/gtk-sharp-2.0/gtk-sharp.dll</HintPath>
<HintPath Condition="$([MSBuild]::IsOsPlatform('OSX'))">/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/gtk-sharp-2.0/gtk-sharp.dll</HintPath>
</Reference>
<ProjectReference Include="..\LibVLCSharp\LibVLCSharp.csproj" />
<PackageReference Include="System.Runtime.InteropServices.RuntimeInformation" Version="4.3.0" />
</ItemGroup>
</Project>
131 changes: 131 additions & 0 deletions LibVLCSharp.GTK/VideoView.cs
@@ -0,0 +1,131 @@
using System;
using System.Runtime.InteropServices;
using Gdk;
using Gtk;
using LibVLCSharp.Shared;

namespace LibVLCSharp.GTK
{
/// <summary>
/// GTK VideoView for Windows, Linux and Mac.
/// Mac is currently unsupported (see https://github.com/mono/gtk-sharp/issues/257)
/// </summary>
public class VideoView : DrawingArea, IVideoView
{
struct Native
{
/// <summary>
/// Gets the window's HWND
/// </summary>
/// <remarks>Window only</remarks>
/// <param name="gdkWindow">The pointer to the GdkWindow object</param>
/// <returns>The window's HWND</returns>
[DllImport("libgdk-win32-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr gdk_win32_drawable_get_handle(IntPtr gdkWindow);

/// <summary>
/// Gets the window's XID
/// </summary>
/// <remarks>Linux X11 only</remarks>
/// <param name="gdkWindow">The pointer to the GdkWindow object</param>
/// <returns>The window's XID</returns>
[DllImport("libgdk-x11-2.0.so.0", CallingConvention = CallingConvention.Cdecl)]
internal static extern uint gdk_x11_drawable_get_xid(IntPtr gdkWindow);

/// <summary>
/// Gets the nsview's handle
/// </summary>
/// <remarks>Mac only</remarks>
/// <param name="gdkWindow">The pointer to the GdkWindow object</param>
/// <returns>The nsview's handle</returns>
[DllImport("libgdk-quartz-2.0.0.dylib")]
internal static extern IntPtr gdk_quartz_window_get_nsview(IntPtr gdkWindow);
}

private MediaPlayer _mediaPlayer;

public VideoView()
{
Color black = Color.Zero;
Color.Parse("black", ref black);
ModifyBg(StateType.Normal, black);

Realized += (s, e) => Attach();
}

public MediaPlayer MediaPlayer
{
get
{
return _mediaPlayer;
}
set
{
if (ReferenceEquals(_mediaPlayer, value))
{
return;
}

Detach();
_mediaPlayer = value;
Attach();
}
}

void Attach()
{
if (!IsRealized || _mediaPlayer == null)
{
return;
}

if (PlatformHelper.IsWindows)
{
MediaPlayer.Hwnd = Native.gdk_win32_drawable_get_handle(GdkWindow.Handle);
}
else if (PlatformHelper.IsLinux)
{
MediaPlayer.XWindow = Native.gdk_x11_drawable_get_xid(GdkWindow.Handle);
}
else if (PlatformHelper.IsMac)
{
MediaPlayer.NsObject = Native.gdk_quartz_window_get_nsview(GdkWindow.Handle);
}
else
{
throw new PlatformNotSupportedException();
}
}

void Detach()
{
if (!IsRealized || _mediaPlayer == null)
{
return;
}

if (PlatformHelper.IsWindows)
{
MediaPlayer.Hwnd = IntPtr.Zero;
}
else if (PlatformHelper.IsLinux)
{
MediaPlayer.XWindow = 0;
}
else if (PlatformHelper.IsMac)
{
MediaPlayer.NsObject = IntPtr.Zero;
}
else
{
throw new PlatformNotSupportedException();
}
}

public override void Dispose()
{
Detach();
base.Dispose();
}
}
}