Skip to content

Commit

Permalink
mediaplayer: Add record binding
Browse files Browse the repository at this point in the history
  • Loading branch information
mfkl committed Aug 30, 2022
1 parent cf7fa94 commit dc5a77a
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 1 deletion.
17 changes: 17 additions & 0 deletions src/LibVLCSharp/Events/MediaPlayerEventManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ internal class MediaPlayerEventManager : EventManager
EventHandler<MediaPlayerProgramDeletedEventArgs>? _mediaPlayerProgramDeleted;
EventHandler<MediaPlayerProgramSelectedEventArgs>? _mediaPlayerProgramSelected;
EventHandler<MediaPlayerProgramUpdatedEventArgs>? _mediaPlayerProgramUpdated;
EventHandler<MediaPlayerRecordChangedEventArgs>? _mediaplayerRecordChanged;

public MediaPlayerEventManager(IntPtr ptr) : base(ptr)
{
Expand Down Expand Up @@ -174,6 +175,10 @@ protected internal override void AttachEvent<T>(EventType eventType, EventHandle
_mediaPlayerProgramSelected += eventHandler as EventHandler<MediaPlayerProgramSelectedEventArgs>;
Attach(eventType, OnProgramSelected);
break;
case EventType.MediaPlayerRecordChanged:
_mediaplayerRecordChanged += eventHandler as EventHandler<MediaPlayerRecordChangedEventArgs>;
Attach(eventType, OnRecordChanged);
break;
default:
OnEventUnhandled(this, eventType);
break;
Expand Down Expand Up @@ -312,6 +317,10 @@ protected internal override void DetachEvent<T>(EventType eventType, EventHandle
_mediaPlayerProgramSelected -= eventHandler as EventHandler<MediaPlayerProgramSelectedEventArgs>;
Detach(eventType);
break;
case EventType.MediaPlayerRecordChanged:
_mediaplayerRecordChanged -= eventHandler as EventHandler<MediaPlayerRecordChangedEventArgs>;
Detach(eventType);
break;
default:
OnEventUnhandled(this, eventType);
break;
Expand Down Expand Up @@ -503,5 +512,13 @@ void OnProgramSelected(IntPtr ptr)
_mediaPlayerProgramSelected?.Invoke(this,
new MediaPlayerProgramSelectedEventArgs(selectionChanged.UnselectedId, selectionChanged.SelectedId));
}

void OnRecordChanged(IntPtr ptr)
{
var recordChanged = RetrieveEvent(ptr).Union.RecordChanged;

_mediaplayerRecordChanged?.Invoke(this,
new MediaPlayerRecordChangedEventArgs(recordChanged.IsRecording, recordChanged.RecordedFilePath.FromUtf8()));
}
}
}
35 changes: 34 additions & 1 deletion src/LibVLCSharp/LibVLCEvents.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ internal enum EventType
MediaPlayerSnapshotTaken = MediaPlayerPausableChanged + 2,
MediaPlayerLengthChanged,
MediaPlayerVout,
MediaPlayerESAdded,
MediaPlayerESAdded = MediaPlayerVout + 2,
MediaPlayerESDeleted,
MediaPlayerESSelected,
MediaPlayerCorked,
Expand All @@ -53,6 +53,7 @@ internal enum EventType
MediaPlayerTitleListChanged,
MediaPlayerTitleSelectionChanged,
MediaPlayerChapterChanged,
MediaPlayerRecordChanged,
MediaListItemAdded = 0x200,
MediaListWillAddItem,
MediaListItemDeleted,
Expand Down Expand Up @@ -161,6 +162,8 @@ internal readonly struct EventUnion
internal readonly VolumeChanged MediaPlayerVolumeChanged;
[FieldOffset(0)]
internal readonly AudioDeviceChanged AudioDeviceChanged;
[FieldOffset(0)]
internal readonly RecordChanged RecordChanged;

// renderer discoverer
[FieldOffset(0)]
Expand Down Expand Up @@ -296,6 +299,13 @@ internal readonly struct AudioDeviceChanged
internal readonly IntPtr Device;
}

[StructLayout(LayoutKind.Sequential)]
internal readonly struct RecordChanged
{
internal readonly bool IsRecording;
internal readonly IntPtr RecordedFilePath;
}

[StructLayout(LayoutKind.Sequential)]
internal readonly struct MediaPlayerMediaChanged
{
Expand Down Expand Up @@ -807,6 +817,29 @@ internal MediaPlayerProgramSelectedEventArgs(int unselectedId, int selectedId)
}
}

/// <summary>
/// The mediaplayer started or stopped recording
/// </summary>
public class MediaPlayerRecordChangedEventArgs : EventArgs
{
/// <summary>
/// True if the mediaplayer started recording,
/// false when the mediaplayer stopped recording
/// </summary>
public readonly bool IsRecording;

/// <summary>
/// filepath of the recorded file, only valid when <see cref="IsRecording"/> is false
/// </summary>
public readonly string? FilePath;

internal MediaPlayerRecordChangedEventArgs(bool isRecording, string? filePath)
{
IsRecording = isRecording;
FilePath = filePath;
}
}

#endregion

#region MediaList events
Expand Down
35 changes: 35 additions & 0 deletions src/LibVLCSharp/MediaPlayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,11 @@ internal static extern int LibVLCMediaPlayerAddSlave(IntPtr mediaPlayer, MediaSl
internal static extern bool LibVLCVideoSetOutputCallbacks(IntPtr mediaplayer, VideoEngine engine, OutputSetup? outputSetup,
OutputCleanup? outputCleanup, OutputSetResize? resize, UpdateOutput updateOutput, Swap swap, MakeCurrent makeCurrent,
GetProcAddress? getProcAddress, FrameMetadata? metadata, OutputSelectPlane? selectPlane, IntPtr opaque);

[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_record")]
internal static extern void LibVLCMediaPlayerRecord(IntPtr mediaplayer, bool enable, IntPtr path);

#if ANDROID
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_set_android_context")]
Expand Down Expand Up @@ -2067,6 +2072,27 @@ public bool SetOutputCallbacks(VideoEngine engine, OutputSetup? outputSetup, Out
FrameMetadata? _frameMetadata;
OutputSelectPlane? _outputSelectPlane;

/// <summary>
/// Start recording
/// <para/>
/// Users should subscribe to <see cref="MediaPlayer.RecordChanged"/> beforehand to get the final filepath of the recorded file and
/// monitor the recording state.
/// <para/>
/// LibVLC 4.0 and later
/// </summary>
/// <param name="directory">path of the recording directory or NULL (use default path)</param>
public void StartRecording(string? directory = null) => Native.LibVLCMediaPlayerRecord(NativeReference, enable: true, directory.ToUtf8());

/// <summary>
/// Stop recording
/// <para/>
/// Users should subscribe to <see cref="MediaPlayer.RecordChanged"/> beforehand to get the final filepath of the recorded file and
/// monitor the recording state.
/// <para/>
/// LibVLC 4.0 and later
/// </summary>
public void StopRecording() => Native.LibVLCMediaPlayerRecord(NativeReference, enable: false, IntPtr.Zero);

readonly MediaConfiguration Configuration = new MediaConfiguration();

#if UNITY
Expand Down Expand Up @@ -3003,6 +3029,15 @@ public event EventHandler<MediaPlayerProgramSelectedEventArgs> ProgramSelected
add => EventManager.AttachEvent(EventType.MediaPlayerProgramSelected, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerProgramSelected, value);
}

/// <summary>
/// The recording state of the mediaplayer changed
/// </summary>
public event EventHandler<MediaPlayerRecordChangedEventArgs> RecordChanged
{
add => EventManager.AttachEvent(EventType.MediaPlayerRecordChanged, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerRecordChanged, value);
}
#endregion

/// <summary>
Expand Down

0 comments on commit dc5a77a

Please sign in to comment.