Skip to content

Commit

Permalink
Implement some basic mpv code
Browse files Browse the repository at this point in the history
  • Loading branch information
karashiiro committed Mar 5, 2024
1 parent 28ecb1b commit 847762c
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 0 deletions.
33 changes: 33 additions & 0 deletions src/simulacrum-dalamud-av/Mpv.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System.Runtime.InteropServices;

namespace Simulacrum.AV;

public static partial class Mpv
{
[LibraryImport("mpv.exe", EntryPoint = "mpv_create")]
internal static partial nint Create();

[LibraryImport("mpv.exe", EntryPoint = "mpv_initialize")]
internal static partial int Initialize(nint client);

[LibraryImport("mpv.exe", EntryPoint = "mpv_terminate_destroy")]
internal static partial int TerminateDestroy(nint client);

[LibraryImport("mpv.exe", EntryPoint = "mpv_command", StringMarshalling = StringMarshalling.Utf8)]
internal static partial int Command(nint client, string[,] args);

[LibraryImport("mpv.exe", EntryPoint = "mpv_set_option")]
internal static partial int SetOption(nint client, ReadOnlySpan<byte> name, int format, ReadOnlySpan<byte> data);

[LibraryImport("mpv.exe", EntryPoint = "mpv_set_option_string")]
internal static partial int SetOptionString(nint client, ReadOnlySpan<byte> name, ReadOnlySpan<byte> data);

[LibraryImport("mpv.exe", EntryPoint = "mpv_get_property")]
internal static partial int GetProperty(nint client, ReadOnlySpan<byte> name, int format, ref nint data);

[LibraryImport("mpv.exe", EntryPoint = "mpv_set_property")]
internal static partial int SetProperty(nint client, ReadOnlySpan<byte> name, int format, ReadOnlySpan<byte> data);

[LibraryImport("mpv.exe", EntryPoint = "mpv_free")]
internal static partial void Free(nint data);
}
58 changes: 58 additions & 0 deletions src/simulacrum-dalamud-av/MpvHandle.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
namespace Simulacrum.AV;

public class MpvHandle : IDisposable
{
private nint _handle = Mpv.Create();

public int Initialize()
{
return _handle != nint.Zero ? Mpv.Initialize(_handle) : -1;
}

public int Command(string[,] args)
{
return _handle != nint.Zero ? Mpv.Command(_handle, args) : -1;
}

public int SetOption(ReadOnlySpan<byte> name, int format, ReadOnlySpan<byte> data)
{
return _handle != nint.Zero ? Mpv.SetOption(_handle, name, format, data) : -1;
}

public int SetOptionString(ReadOnlySpan<byte> name, ReadOnlySpan<byte> data)
{
return _handle != nint.Zero ? Mpv.SetOptionString(_handle, name, data) : -1;
}

public int GetProperty(ReadOnlySpan<byte> name, int format, ref nint data)
{
return _handle != nint.Zero ? Mpv.GetProperty(_handle, name, format, ref data) : -1;
}

public int SetProperty(ReadOnlySpan<byte> name, int format, ReadOnlySpan<byte> data)
{
return _handle != nint.Zero ? Mpv.SetProperty(_handle, name, format, data) : -1;
}

private void ReleaseUnmanagedResources()
{
if (_handle == nint.Zero)
{
return;
}

Mpv.TerminateDestroy(_handle);
_handle = nint.Zero;
}

public void Dispose()
{
ReleaseUnmanagedResources();
GC.SuppressFinalize(this);
}

~MpvHandle()
{
ReleaseUnmanagedResources();
}
}
64 changes: 64 additions & 0 deletions src/simulacrum-dalamud-plugin/Drawing/MpvMediaSource.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using System.Globalization;
using R3;
using Simulacrum.AV;
using Simulacrum.Drawing.Common;

namespace Simulacrum.Drawing;

public class MpvMediaSource : IMediaSource, IDisposable
{
private readonly MpvHandle _handle;

private readonly IDisposable _unsubscribeAll;

public MpvMediaSource(string? uri, IReadOnlyPlaybackTracker sync)
{
ArgumentNullException.ThrowIfNull(uri);

_handle = new MpvHandle();
_handle.Initialize();

_handle.SetOptionString("keep-open"u8, "always"u8);

_handle.Command(new[,] { { "loadfile", uri } });

var unsubscribePause = sync.OnPause()
.Subscribe(_handle, static (_, mpv) => mpv.SetProperty("pause"u8, 1, "yes"u8));
var unsubscribePlay =
sync.OnPlay().Subscribe(_handle, static (_, mpv) => mpv.SetProperty("pause"u8, 1, "no"u8));
var unsubscribePan = sync.OnPan().Subscribe(_handle,
static (t, mpv) =>
{
mpv.Command(new[,] { { "seek", t.TotalSeconds.ToString(CultureInfo.InvariantCulture), "absolute" } });
});

_unsubscribeAll = Disposable.Combine(unsubscribePause, unsubscribePlay, unsubscribePan);
}

public void RenderTo(Span<byte> buffer)
{
throw new NotImplementedException();
}

public void RenderTo(Span<byte> buffer, out TimeSpan delay)
{
throw new NotImplementedException();
}

public int PixelSize()
{
throw new NotImplementedException();
}

public IntVector2 Size()
{
throw new NotImplementedException();
}

public void Dispose()
{
_unsubscribeAll.Dispose();
_handle.Dispose();
GC.SuppressFinalize(this);
}
}

0 comments on commit 847762c

Please sign in to comment.