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

mediaplayer: Add record binding #305

Merged
merged 1 commit into from
Aug 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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