Commit 8d736293 authored by Martin Finkel's avatar Martin Finkel

Tests now use the nuget package for libvlc. Added renderer APIs on Instance and MediaPlayer

parent 8c15518c
using System;
using System.IO;
using NUnit.Framework;
using VideoLAN.LibVLC;
namespace LibVLCSharp.Tests
{
public abstract class BaseSetup
{
[SetUp]
public void SetUp()
{
Core.Initialize();
}
protected string RealStreamMediaPath => "http://streams.videolan.org/streams/mp3/Owner-MPEG2.5.mp3";
protected string RealMp3Path =>
Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "sample.mp3");
}
}
\ No newline at end of file
......@@ -5,7 +5,7 @@ using VideoLAN.LibVLC;
namespace LibVLCSharp.Tests
{
[TestFixture]
public class DialogTests
public class DialogTests : BaseSetup
{
const string UrlRequireAuth = "http://httpbin.org/basic-auth/user/passwd";
const string Username = "username";
......
......@@ -4,7 +4,7 @@ using VideoLAN.LibVLC;
namespace LibVLCSharp.Tests
{
[TestFixture]
public class EqualizerTests
public class EqualizerTests : BaseSetup
{
[Test]
public void BasicNativeCallTest()
......
......@@ -9,7 +9,7 @@ using Media = VideoLAN.LibVLC.Media;
namespace LibVLCSharp.Tests
{
[TestFixture]
public class EventManagerTests
public class EventManagerTests : BaseSetup
{
[Test]
public void MetaChangedEventSubscribe()
......@@ -32,7 +32,7 @@ namespace LibVLCSharp.Tests
{
// FIXME
var instance = new Instance();
var media = new Media(instance, RealMediaPath, Media.FromType.FromPath);
var media = new Media(instance, RealMp3Path, Media.FromType.FromPath);
var subItem = new Media(instance, Path.GetTempFileName(), Media.FromType.FromPath);
var eventManager = media.EventManager;
......@@ -47,22 +47,11 @@ namespace LibVLCSharp.Tests
media.SubItems.Unlock();
Assert.True(eventHandlerCalled);
}
string RealMediaPath
{
get
{
var dir = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
//var binDir = Path.Combine(dir, "..\\..\\..\\");
var files = Directory.GetFiles(dir);
return files.First(f => f.Contains("Klang"));
}
}
[Test]
public void DurationChanged()
{
var media = new Media(new Instance(), RealMediaPath, Media.FromType.FromPath);
var media = new Media(new Instance(), RealMp3Path, Media.FromType.FromPath);
var called = false;
long duration = 0;
......@@ -81,7 +70,7 @@ namespace LibVLCSharp.Tests
[Test]
public void FreedMedia()
{
var media = new Media(new Instance(), RealMediaPath, Media.FromType.FromPath);
var media = new Media(new Instance(), RealMp3Path, Media.FromType.FromPath);
var eventCalled = false;
media.EventManager.MediaFreed += (sender, args) =>
{
......@@ -96,7 +85,7 @@ namespace LibVLCSharp.Tests
[Test]
public async Task StateChanged()
{
var media = new Media(new Instance(), RealMediaPath, Media.FromType.FromPath);
var media = new Media(new Instance(), RealMp3Path, Media.FromType.FromPath);
var tcs = new TaskCompletionSource<bool>();
var openingCalled = false;
media.EventManager.StateChanged += (sender, args) =>
......@@ -121,7 +110,7 @@ namespace LibVLCSharp.Tests
[Test]
public void SubItemTreeAdded()
{
var media = new Media(new Instance(), RealMediaPath, Media.FromType.FromPath);
var media = new Media(new Instance(), RealMp3Path, Media.FromType.FromPath);
//TODO: Implement MediaList.cs
Assert.Fail();
}
......
......@@ -10,7 +10,7 @@ using VideoLAN.LibVLC.Events;
namespace LibVLCSharp.Tests
{
[TestFixture]
public class InstanceTests
public class InstanceTests : BaseSetup
{
[Test]
public void DisposeInstanceNativeRelease()
......
......@@ -11,6 +11,7 @@
<PackageReference Include="Moq" Version="4.7.142" />
<PackageReference Include="NUnit" Version="3.8.1" />
<PackageReference Include="NUnit3TestAdapter" Version="3.9.0" />
<PackageReference Include="VideoLAN.LibVLC.Windows" Version="3.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LibVLCSharp\LibVLCSharp.csproj" />
......
......@@ -5,7 +5,7 @@ using VideoLAN.LibVLC;
namespace LibVLCSharp.Tests
{
[TestFixture]
public class MediaDiscovererTests
public class MediaDiscovererTests : BaseSetup
{
[Test]
public void CreateStartAndStopDiscoverer()
......
......@@ -8,7 +8,7 @@ using MediaList = VideoLAN.LibVLC.MediaList;
namespace LibVLCSharp.Tests
{
[TestFixture]
public class MediaListTests
public class MediaListTests : BaseSetup
{
[Test]
public void AddAndRemoveMediaFromMediaList()
......
......@@ -11,7 +11,7 @@ using MediaPlayer = VideoLAN.LibVLC.MediaPlayer;
namespace LibVLCSharp.Tests
{
[TestFixture]
public class MediaPlayerTests
public class MediaPlayerTests : BaseSetup
{
[Test]
public void CreateAndDestroy()
......
......@@ -9,7 +9,7 @@ using Media = VideoLAN.LibVLC.Media;
namespace LibVLCSharp.Tests
{
[TestFixture]
public class MediaTests
public class MediaTests : BaseSetup
{
[Test]
public void CreateMedia()
......@@ -75,8 +75,6 @@ namespace LibVLCSharp.Tests
}
}
string RealStreamMediaPath => "http://streams.videolan.org/streams/mp3/Owner-MPEG2.5.mp3";
[Test]
public void Duplicate()
{
......
using System.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NUnit.Framework;
using VideoLAN.LibVLC;
using static System.Diagnostics.Debug;
using Assert = NUnit.Framework.Assert;
namespace LibVLCSharp.Tests
{
[TestFixture]
public class RendererDiscovererTests
public class RendererDiscovererTests : BaseSetup
{
[Test]
public async Task DiscoverItems()
{
var instance = new Instance();
Core.Initialize();
var rendererDiscoverer = new RendererDiscoverer(instance, "microdns");
var em = rendererDiscoverer.EventManager;
var itemAdded = false;
var instance = new Instance(new []{"--verbose=2"});
instance.Log += (sender, args) =>
{
WriteLine(args.Message);
};
var mp = new MediaPlayer(instance)
{
Media = new Media(instance, "http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4",
Media.FromType.FromLocation)
};
// Assert.True(mp.Play());
var rendererList = instance.RendererList;
Assert.IsNotEmpty(rendererList);
em.ItemAdded += (sender, args) =>
var rendererDiscoverer = new RendererDiscoverer(instance, /*"microdns"*/ rendererList[0].Name);
var rendererItems = new List<RendererItem>();
var tcs = new TaskCompletionSource<bool>();
rendererDiscoverer.EventManager.ItemAdded += (sender, args) =>
{
WriteLine($"New item discovered: {args.RendererItem.Name} of type {args.RendererItem.Type}");
if(args.RendererItem.CanRenderVideo)
WriteLine("Can render video");
if(args.RendererItem.CanRenderAudio)
WriteLine("Can render audio");
itemAdded = true;
tcs.SetResult(true);
rendererItems.Add(args.RendererItem);
};
if(!rendererDiscoverer.Start())
NUnit.Framework.Assert.Fail();
await Task.Delay(10000);
Assert.True(rendererDiscoverer.Start());
NUnit.Framework.Assert.True(itemAdded);
}
//await Task.Delay(10000);
await tcs.Task;
Assert.True(tcs.Task.Result);
Assert.IsNotEmpty(rendererItems);
Assert.True(mp.SetRenderer(rendererItems.First()));
[Test]
public void RetrieveListInformation()
{
var rd = new RendererDiscoverer(new Instance(), "rd");
NUnit.Framework.Assert.Positive(rd.List.Length);
Console.ReadKey();
}
}
}
......@@ -4,7 +4,7 @@ using VideoLAN.LibVLC;
namespace LibVLCSharp.Tests
{
[TestFixture]
public class VersionCheckTests
public class VersionCheckTests : BaseSetup
{
[Test]
public void ShouldThrowIfDllVersionNotHighEnough()
......
......@@ -51,7 +51,7 @@ namespace VideoLAN.LibVLC
[SuppressUnmanagedCodeSecurity]
[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_new")]
internal static extern unsafe IntPtr LibVLCNew(int argc, sbyte** argv);
internal static extern IntPtr LibVLCNew(int argc, IntPtr[] argv);
[SuppressUnmanagedCodeSecurity]
[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl,
......@@ -150,6 +150,16 @@ namespace VideoLAN.LibVLC
EntryPoint = "libvlc_dialog_set_callbacks")]
internal static extern void LibVLCDialogSetCallbacks(IntPtr instance, IntPtr callbacks, IntPtr data);
[SuppressUnmanagedCodeSecurity]
[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_renderer_discoverer_list_get")]
internal static extern ulong LibVLCRendererDiscovererGetList(IntPtr instance, ref IntPtr discovererList);
[SuppressUnmanagedCodeSecurity]
[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_renderer_discoverer_list_release")]
internal static extern void LibVLCRendererDiscovererReleaseList(IntPtr discovererList, ulong count);
#region Windows
/// <summary>
......@@ -258,21 +268,30 @@ namespace VideoLAN.LibVLC
/// <para>cross-platform compatibility with regards to libvlc_new() arguments.</para>
/// <para>We recommend that you do not use them, other than when debugging.</para>
/// </remarks>
public Instance(int argc = 0, string[] args = null)
public Instance(string[] args = null)
: base(() =>
{
unsafe
var utf8Args = new IntPtr[args?.Length ?? 0];
try
{
if (args == null || !args.Any())
return Native.LibVLCNew(argc, null);
fixed (byte* arg0 = Encoding.ASCII.GetBytes(args[0]),
arg1 = Encoding.ASCII.GetBytes(args[1]),
arg2 = Encoding.ASCII.GetBytes(args[2]))
for (var i = 0; i < utf8Args.Length; i++)
{
sbyte*[] arr = { (sbyte*)arg0, (sbyte*)arg1, (sbyte*)arg2 };
fixed (sbyte** argv = arr)
var bytes = Encoding.UTF8.GetBytes(args[i]);
var buffer = Marshal.AllocHGlobal(bytes.Length + 1);
Marshal.Copy(bytes, 0, buffer, bytes.Length);
Marshal.WriteByte(buffer, bytes.Length, 0);
utf8Args[i] = buffer;
}
return Native.LibVLCNew(utf8Args.Length, utf8Args);
}
finally
{
foreach (var arg in utf8Args)
{
if (arg != IntPtr.Zero)
{
return Native.LibVLCNew(argc, argv);
Marshal.FreeHGlobal(arg);
}
}
}
......@@ -659,6 +678,43 @@ namespace VideoLAN.LibVLC
public bool DialogHandlersSet => _dialogCbsPtr != IntPtr.Zero;
public RendererDescription[] RendererList
{
get
{
// TODO: Move marshalling logic to generic MarshalUtils func
var discoverList = IntPtr.Zero;
var count = Native.LibVLCRendererDiscovererGetList(NativeReference, ref discoverList);
if (count == 0) return Array.Empty<RendererDescription>();
var rendererDiscovererDescription = new RendererDescription[(int)count];
for (var i = 0; i < (int)count; i++)
{
var ptr = Marshal.ReadIntPtr(discoverList, i * IntPtr.Size);
var managedStruct = (RendererDescription)Marshal.PtrToStructure(ptr, typeof(RendererDescription));
rendererDiscovererDescription[i] = managedStruct;
}
Native.LibVLCRendererDiscovererReleaseList(discoverList, count);
return rendererDiscovererDescription;
}
}
public struct RendererDescription
{
public string Name { get; }
public string LongName { get; }
public RendererDescription(string name, string longName)
{
Name = name;
LongName = longName;
}
}
/// <summary>
/// Code taken from Vlc.DotNet
/// </summary>
......
......@@ -617,6 +617,11 @@ namespace VideoLAN.LibVLC
[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_audio_output_device_list_release")]
internal static extern void LibVLCAudioOutputDeviceListRelease(IntPtr list);
[SuppressUnmanagedCodeSecurity]
[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_set_renderer")]
internal static extern int LibVLCMediaPlayerSetRenderer(IntPtr mediaplayer, IntPtr renderItem);
}
MediaPlayerEventManager _eventManager;
......@@ -1589,6 +1594,10 @@ namespace VideoLAN.LibVLC
public bool UpdateViewpoint(VideoViewpoint viewpoint, bool absolute) =>
Native.LibVLCVideoUpdateViewpoint(NativeReference, viewpoint, absolute) == 0;
[LibVLC(3)]
public bool SetRenderer(RendererItem rendererItem) =>
Native.LibVLCMediaPlayerSetRenderer(NativeReference, rendererItem.NativeReference) == 0;
#region Enums
......
......@@ -6,8 +6,6 @@ namespace VideoLAN.LibVLC
{
public class RendererDiscoverer : Internal
{
readonly IntPtr _instanceNativeReference;
struct Native
{
[SuppressUnmanagedCodeSecurity]
......@@ -34,22 +32,12 @@ namespace VideoLAN.LibVLC
[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_renderer_discoverer_event_manager")]
internal static extern IntPtr LibVLCRendererDiscovererEventManager(IntPtr rendererDiscoverer);
[SuppressUnmanagedCodeSecurity]
[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_renderer_discoverer_list_get")]
internal static extern ulong LibVLCRendererDiscovererGetList(IntPtr instance, ref IntPtr discovererList);
[SuppressUnmanagedCodeSecurity]
[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_renderer_discoverer_list_release")]
internal static extern void LibVLCRendererDiscovererReleaseList(IntPtr discovererList, ulong count);
}
public RendererDiscoverer(Instance instance, string name)
: base(() => Native.LibVLCRendererDiscovererNew(instance.NativeReference, name), Native.LibVLCRendererDiscovererRelease)
: base(() => Native.LibVLCRendererDiscovererNew(instance.NativeReference, name),
Native.LibVLCRendererDiscovererRelease)
{
_instanceNativeReference = instance.NativeReference;
}
RendererDiscovererEventManager _eventManager;
......@@ -70,42 +58,6 @@ namespace VideoLAN.LibVLC
public bool Start() => Native.LibVLCRendererDiscovererStart(NativeReference) == 0;
public void Stop() => Native.LibVLCRendererDiscovererStop(NativeReference);
public Description[] List
{
get
{
var discoverList = IntPtr.Zero;
var count = Native.LibVLCRendererDiscovererGetList(_instanceNativeReference, ref discoverList);
if (count == 0) return Array.Empty<Description>();
var rendererDiscovererDescription = new Description[(int)count];
for (var i = 0; i < (int)count; i++)
{
var ptr = Marshal.ReadIntPtr(discoverList, i * IntPtr.Size);
var managedStruct = (Description)Marshal.PtrToStructure(ptr, typeof(Description));
rendererDiscovererDescription[i] = managedStruct;
}
Native.LibVLCRendererDiscovererReleaseList(discoverList, count);
return rendererDiscovererDescription;
}
}
public struct Description
{
public string Name { get; }
public string LongName { get; }
public Description(string name, string longName)
{
Name = name;
LongName = longName;
}
}
}
public class RendererItem : Internal
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment