using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using LibVLCSharp.Shared.Helpers;
using LibVLCSharp.Shared.Structures;
namespace LibVLCSharp.Shared
{
///
/// The MediaPlayer type is used to control playback, set renderers, provide events and much more
///
public class MediaPlayer : Internal
{
readonly struct Native
{
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_new")]
internal static extern IntPtr LibVLCMediaPlayerNew(IntPtr libvlc);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_release")]
internal static extern void LibVLCMediaPlayerRelease(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_new_from_media")]
internal static extern IntPtr LibVLCMediaPlayerNewFromMedia(IntPtr media);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_set_media")]
internal static extern void LibVLCMediaPlayerSetMedia(IntPtr mediaPlayer, IntPtr media);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_get_media")]
internal static extern IntPtr LibVLCMediaPlayerGetMedia(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_event_manager")]
internal static extern IntPtr LibVLCMediaPlayerEventManager(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_is_playing")]
internal static extern int LibVLCMediaPlayerIsPlaying(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_play")]
internal static extern int LibVLCMediaPlayerPlay(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_set_pause")]
internal static extern void LibVLCMediaPlayerSetPause(IntPtr mediaPlayer, bool pause);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_pause")]
internal static extern void LibVLCMediaPlayerPause(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_stop")]
internal static extern void LibVLCMediaPlayerStop(IntPtr mediaPlayer);
#if APPLE || NETFRAMEWORK || NETSTANDARD
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_set_nsobject")]
internal static extern void LibVLCMediaPlayerSetNsobject(IntPtr mediaPlayer, IntPtr drawable);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_get_nsobject")]
internal static extern IntPtr LibVLCMediaPlayerGetNsobject(IntPtr mediaPlayer);
#endif
#if NETFRAMEWORK || NETSTANDARD
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_set_xwindow")]
internal static extern void LibVLCMediaPlayerSetXwindow(IntPtr mediaPlayer, uint drawable);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_get_xwindow")]
internal static extern uint LibVLCMediaPlayerGetXwindow(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_set_hwnd")]
internal static extern void LibVLCMediaPlayerSetHwnd(IntPtr mediaPlayer, IntPtr drawable);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_get_hwnd")]
internal static extern IntPtr LibVLCMediaPlayerGetHwnd(IntPtr mediaPlayer);
#endif
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_get_length")]
internal static extern long LibVLCMediaPlayerGetLength(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_get_time")]
internal static extern long LibVLCMediaPlayerGetTime(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_set_time")]
internal static extern void LibVLCMediaPlayerSetTime(IntPtr mediaPlayer, long time);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_get_position")]
internal static extern float LibVLCMediaPlayerGetPosition(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_set_position")]
internal static extern void LibVLCMediaPlayerSetPosition(IntPtr mediaPlayer, float position);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_set_chapter")]
internal static extern void LibVLCMediaPlayerSetChapter(IntPtr mediaPlayer, int chapter);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_get_chapter")]
internal static extern int LibVLCMediaPlayerGetChapter(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_get_chapter_count")]
internal static extern int LibVLCMediaPlayerGetChapterCount(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_will_play")]
internal static extern int LibVLCMediaPlayerWillPlay(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_get_chapter_count_for_title")]
internal static extern int LibVLCMediaPlayerGetChapterCountForTitle(IntPtr mediaPlayer, int title);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_set_title")]
internal static extern void LibVLCMediaPlayerSetTitle(IntPtr mediaPlayer, int title);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_get_title")]
internal static extern int LibVLCMediaPlayerGetTitle(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_get_title_count")]
internal static extern int LibVLCMediaPlayerGetTitleCount(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_previous_chapter")]
internal static extern void LibVLCMediaPlayerPreviousChapter(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_next_chapter")]
internal static extern void LibVLCMediaPlayerNextChapter(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_get_rate")]
internal static extern float LibVLCMediaPlayerGetRate(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_set_rate")]
internal static extern int LibVLCMediaPlayerSetRate(IntPtr mediaPlayer, float rate);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_get_state")]
internal static extern VLCState LibVLCMediaPlayerGetState(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_get_fps")]
internal static extern float LibVLCMediaPlayerGetFps(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_has_vout")]
internal static extern uint LibVLCMediaPlayerHasVout(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_is_seekable")]
internal static extern int LibVLCMediaPlayerIsSeekable(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_can_pause")]
internal static extern int LibVLCMediaPlayerCanPause(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_program_scrambled")]
internal static extern int LibVLCMediaPlayerProgramScrambled(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_next_frame")]
internal static extern void LibVLCMediaPlayerNextFrame(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_navigate")]
internal static extern void LibVLCMediaPlayerNavigate(IntPtr mediaPlayer, uint navigate);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_set_video_title_display")]
internal static extern void LibVLCMediaPlayerSetVideoTitleDisplay(IntPtr mediaPlayer, Position position, uint timeout);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_toggle_fullscreen")]
internal static extern void LibVLCToggleFullscreen(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_set_fullscreen")]
internal static extern void LibVLCSetFullscreen(IntPtr mediaPlayer, int fullscreen);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_get_fullscreen")]
internal static extern int LibVLCGetFullscreen(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_toggle_teletext")]
internal static extern void LibVLCToggleTeletext(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_set_equalizer")]
internal static extern int LibVLCMediaPlayerSetEqualizer(IntPtr mediaPlayer, IntPtr equalizer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_audio_set_callbacks")]
internal static extern void LibVLCAudioSetCallbacks(IntPtr mediaPlayer, LibVLCAudioPlayCb play, LibVLCAudioPauseCb? pause,
LibVLCAudioResumeCb? resume, LibVLCAudioFlushCb? flush, LibVLCAudioDrainCb? drain, IntPtr opaque);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_audio_set_volume_callback")]
internal static extern void LibVLCAudioSetVolumeCallback(IntPtr mediaPlayer, LibVLCVolumeCb? volumeCallback);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_audio_set_format_callbacks")]
internal static extern void LibVLCAudioSetFormatCallbacks(IntPtr mediaPlayer, LibVLCAudioSetupCb setup, LibVLCAudioCleanupCb? cleanup);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_audio_set_format")]
internal static extern void LibVLCAudioSetFormat(IntPtr mediaPlayer, IntPtr format,
uint rate, uint channels);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_audio_output_device_enum")]
internal static extern IntPtr LibVLCAudioOutputDeviceEnum(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_audio_output_device_set")]
internal static extern void LibVLCAudioOutputDeviceSet(IntPtr mediaPlayer, IntPtr module, IntPtr deviceId);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_audio_output_device_get")]
internal static extern IntPtr LibVLCAudioOutputDeviceGet(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_audio_output_set")]
internal static extern int LibVLCAudioOutputSet(IntPtr mediaPlayer, IntPtr name);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_audio_toggle_mute")]
internal static extern void LibVLCAudioToggleMute(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_audio_get_mute")]
internal static extern int LibVLCAudioGetMute(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_audio_set_mute")]
internal static extern void LibVLCAudioSetMute(IntPtr mediaPlayer, int status);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_audio_get_volume")]
internal static extern int LibVLCAudioGetVolume(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_audio_set_volume")]
internal static extern int LibVLCAudioSetVolume(IntPtr mediaPlayer, int volume);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_audio_get_track_count")]
internal static extern int LibVLCAudioGetTrackCount(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_audio_get_track_description")]
internal static extern IntPtr LibVLCAudioGetTrackDescription(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_audio_get_track")]
internal static extern int LibVLCAudioGetTrack(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_audio_set_track")]
internal static extern int LibVLCAudioSetTrack(IntPtr mediaPlayer, int track);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_audio_get_channel")]
internal static extern AudioOutputChannel LibVLCAudioGetChannel(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_audio_set_channel")]
internal static extern int LibVLCAudioSetChannel(IntPtr mediaPlayer, AudioOutputChannel channel);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_audio_get_delay")]
internal static extern long LibVLCAudioGetDelay(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_audio_set_delay")]
internal static extern int LibVLCAudioSetDelay(IntPtr mediaPlayer, long delay);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_set_callbacks")]
internal static extern void LibVLCVideoSetCallbacks(IntPtr mediaPlayer, LibVLCVideoLockCb lockCallback,
LibVLCVideoUnlockCb? unlock, LibVLCVideoDisplayCb? display, IntPtr opaque);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_set_format")]
internal static extern void LibVLCVideoSetFormat(IntPtr mediaPlayer, IntPtr chroma,
uint width, uint height, uint pitch);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_set_format_callbacks")]
internal static extern void LibVLCVideoSetFormatCallbacks(IntPtr mediaPlayer, LibVLCVideoFormatCb setup,
LibVLCVideoCleanupCb? cleanup);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_set_key_input")]
internal static extern void LibVLCVideoSetKeyInput(IntPtr mediaPlayer, int enable);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_set_mouse_input")]
internal static extern void LibVLCVideoSetMouseInput(IntPtr mediaPlayer, int enable);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_get_size")]
internal static extern int LibVLCVideoGetSize(IntPtr mediaPlayer, uint num, ref uint px, ref uint py);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_get_cursor")]
internal static extern int LibVLCVideoGetCursor(IntPtr mediaPlayer, uint num, ref int px, ref int py);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_get_scale")]
internal static extern float LibVLCVideoGetScale(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_set_scale")]
internal static extern void LibVLCVideoSetScale(IntPtr mediaPlayer, float factor);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_get_aspect_ratio")]
internal static extern IntPtr LibVLCVideoGetAspectRatio(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_set_aspect_ratio")]
internal static extern void LibVLCVideoSetAspectRatio(IntPtr mediaPlayer, IntPtr aspect);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_get_spu")]
internal static extern int LibVLCVideoGetSpu(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_get_spu_count")]
internal static extern int LibVLCVideoGetSpuCount(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_get_spu_description")]
internal static extern IntPtr LibVLCVideoGetSpuDescription(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_set_spu")]
internal static extern int LibVLCVideoSetSpu(IntPtr mediaPlayer, int spu);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_get_spu_delay")]
internal static extern long LibVLCVideoGetSpuDelay(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_set_spu_delay")]
internal static extern int LibVLCVideoSetSpuDelay(IntPtr mediaPlayer, long delay);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_get_title_description")]
internal static extern IntPtr LibVLCVideoGetTitleDescription(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_get_full_title_descriptions")]
internal static extern int LibVLCMediaPlayerGetFullTitleDescriptions(IntPtr mediaPlayer, IntPtr titles);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_get_chapter_description")]
internal static extern IntPtr LibVLCVideoGetChapterDescription(IntPtr mediaPlayer,
int title);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_title_descriptions_release")]
internal static extern void LibVLCTitleDescriptionsRelease(IntPtr titles, uint count);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_get_full_chapter_descriptions")]
internal static extern int LibVLCMediaPlayerGetFullChapterDescriptions(IntPtr mediaPlayer, int titleIndex, out IntPtr chapters);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_chapter_descriptions_release")]
internal static extern void LibVLCChapterDescriptionsRelease(IntPtr chapters, uint count);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_get_crop_geometry")]
internal static extern IntPtr LibVLCVideoGetCropGeometry(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_set_crop_geometry")]
internal static extern void LibVLCVideoSetCropGeometry(IntPtr mediaPlayer, IntPtr geometry);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_get_teletext")]
internal static extern int LibVLCVideoGetTeletext(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_set_teletext")]
internal static extern void LibVLCVideoSetTeletext(IntPtr mediaPlayer, int page);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_get_track_count")]
internal static extern int LibVLCVideoGetTrackCount(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_get_track_description")]
internal static extern IntPtr LibVLCVideoGetTrackDescription(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_get_track")]
internal static extern int LibVLCVideoGetTrack(IntPtr mediaPlayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_set_track")]
internal static extern int LibVLCVideoSetTrack(IntPtr mediaPlayer, int track);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_take_snapshot")]
internal static extern int LibVLCVideoTakeSnapshot(IntPtr mediaPlayer, uint num,
IntPtr filepath, uint width, uint height);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_set_deinterlace")]
internal static extern void LibVLCVideoSetDeinterlace(IntPtr mediaPlayer, IntPtr mode);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_get_marquee_int")]
internal static extern int LibVLCVideoGetMarqueeInt(IntPtr mediaPlayer, VideoMarqueeOption option);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_get_marquee_string")]
internal static extern IntPtr LibVLCVideoGetMarqueeString(IntPtr mediaPlayer, VideoMarqueeOption option);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_set_marquee_int")]
internal static extern void LibVLCVideoSetMarqueeInt(IntPtr mediaPlayer, VideoMarqueeOption option, int marqueeValue);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_set_marquee_string")]
internal static extern void LibVLCVideoSetMarqueeString(IntPtr mediaPlayer, VideoMarqueeOption option, IntPtr marqueeValue);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_get_logo_int")]
internal static extern int LibVLCVideoGetLogoInt(IntPtr mediaPlayer, VideoLogoOption option);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_set_logo_int")]
internal static extern void LibVLCVideoSetLogoInt(IntPtr mediaPlayer, VideoLogoOption option, int value);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_set_logo_string")]
internal static extern void LibVLCVideoSetLogoString(IntPtr mediaPlayer, VideoLogoOption option, IntPtr logoOptionValue);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_get_adjust_int")]
internal static extern int LibVLCVideoGetAdjustInt(IntPtr mediaPlayer, VideoAdjustOption option);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_set_adjust_int")]
internal static extern void LibVLCVideoSetAdjustInt(IntPtr mediaPlayer, VideoAdjustOption option, int value);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_get_adjust_float")]
internal static extern float LibVLCVideoGetAdjustFloat(IntPtr mediaPlayer, VideoAdjustOption option);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_set_adjust_float")]
internal static extern void LibVLCVideoSetAdjustFloat(IntPtr mediaPlayer, VideoAdjustOption option, float value);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_add_slave")]
internal static extern int LibVLCMediaPlayerAddSlave(IntPtr mediaPlayer, MediaSlaveType mediaSlaveType,
IntPtr uri, bool selectWhenloaded);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_new_viewpoint")]
internal static extern IntPtr LibVLCVideoNewViewpoint();
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_video_update_viewpoint")]
internal static extern int LibVLCVideoUpdateViewpoint(IntPtr mediaPlayer, IntPtr viewpoint, bool absolute);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_track_description_list_release")]
internal static extern void LibVLCTrackDescriptionListRelease(IntPtr trackDescription);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_audio_output_device_list_release")]
internal static extern void LibVLCAudioOutputDeviceListRelease(IntPtr list);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_set_renderer")]
internal static extern int LibVLCMediaPlayerSetRenderer(IntPtr mediaplayer, IntPtr renderItem);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_get_role")]
internal static extern MediaPlayerRole LibVLCMediaPlayerGetRole(IntPtr mediaplayer);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_set_role")]
internal static extern int LibVLCMediaPlayerSetRole(IntPtr mediaplayer, MediaPlayerRole role);
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_retain")]
internal static extern void LibVLCMediaPlayerRetain(IntPtr mediaplayer);
#if ANDROID
[DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "libvlc_media_player_set_android_context")]
internal static extern void LibVLCMediaPlayerSetAndroidContext(IntPtr mediaPlayer, IntPtr aWindow);
#endif
}
MediaPlayerEventManager? _eventManager;
///
/// The GCHandle to be passed to callbacks as userData
///
GCHandle _gcHandle;
/// Create an empty Media Player object
///
/// the libvlc instance in which the Media Player
/// should be created.
///
/// a new media player object, or NULL on error.
public MediaPlayer(LibVLC libVLC)
: base(() => Native.LibVLCMediaPlayerNew(libVLC.NativeReference), Native.LibVLCMediaPlayerRelease)
{
_gcHandle = GCHandle.Alloc(this);
}
/// Create a Media Player object from a Media
///
/// the media. Afterwards the p_md can be safely
/// destroyed.
///
/// a new media player object, or NULL on error.
public MediaPlayer(Media media)
: base(() => Native.LibVLCMediaPlayerNewFromMedia(media.NativeReference), Native.LibVLCMediaPlayerRelease)
{
_gcHandle = GCHandle.Alloc(this);
}
///
/// Get the media used by the media_player.
/// Set the media that will be used by the media_player.
/// If any, previous md will be released.
/// Note: It is safe to release the Media on the C# side after it's been set on the MediaPlayer successfully
///
public Media? Media
{
get
{
var mediaPtr = Native.LibVLCMediaPlayerGetMedia(NativeReference);
return mediaPtr == IntPtr.Zero ? null : new Media(mediaPtr);
}
set => Native.LibVLCMediaPlayerSetMedia(NativeReference, value?.NativeReference ?? IntPtr.Zero);
}
///
/// return true if the media player is playing, false otherwise
///
public bool IsPlaying => Native.LibVLCMediaPlayerIsPlaying(NativeReference) != 0;
///
/// Start playback with Media that is set
/// If playback was already started, this method has no effect
///
/// true if successful
public bool Play()
{
Media?.AddOption(Configuration);
return Native.LibVLCMediaPlayerPlay(NativeReference) == 0;
}
///
/// Set media and start playback
///
///
/// true if successful
public bool Play(Media media)
{
Media = media;
return Play();
}
///
/// Pause or resume (no effect if there is no media).
/// version LibVLC 1.1.1 or later
///
/// play/resume if true, pause if false
public void SetPause(bool pause) => Native.LibVLCMediaPlayerSetPause(NativeReference, pause);
///
/// Toggle pause (no effect if there is no media)
///
public void Pause() => Native.LibVLCMediaPlayerPause(NativeReference);
///
/// Stop the playback (no effect if there is no media)
/// warning:
/// This is synchronous, and will block until all VLC threads have been joined.
/// Calling this from a VLC callback is a bound to cause a deadlock.
///
public void Stop() => Native.LibVLCMediaPlayerStop(NativeReference);
#if APPLE || NETFRAMEWORK || NETSTANDARD
///
/// Get the NSView handler previously set
/// return the NSView handler or 0 if none where set
///
///
/// Set the NSView handler where the media player should render its video output.
/// Use the vout called "macosx".
///
/// The drawable is an NSObject that follow the
/// VLCOpenGLVideoViewEmbedding protocol: VLCOpenGLVideoViewEmbedding NSObject
/// Or it can be an NSView object.
/// If you want to use it along with Qt4 see the QMacCocoaViewContainer.
/// Then the following code should work: { NSView *video = [[NSView
/// alloc] init]; QMacCocoaViewContainer *container = new
/// QMacCocoaViewContainer(video, parent);
/// libvlc_media_player_set_nsobject(mp, video); [video release]; }
/// You can find a live example in VLCVideoView in VLCKit.framework.
///
public IntPtr NsObject
{
get => Native.LibVLCMediaPlayerGetNsobject(NativeReference);
set => Native.LibVLCMediaPlayerSetNsobject(NativeReference, value);
}
#endif
#if NETFRAMEWORK || NETSTANDARD
///
/// Set an X Window System drawable where the media player should render its video output.
/// The call takes effect when the playback starts. If it is already started, it might need to be stopped before changes apply.
/// If LibVLC was built without X11 output support, then this function has no effects.
/// By default, LibVLC will capture input events on the video rendering area.
/// Use libvlc_video_set_mouse_input() and libvlc_video_set_key_input() to disable that and deliver events to the parent window / to the application instead.
/// By design, the X11 protocol delivers input events to only one recipient.
///
/// Warning:
/// The application must call the XInitThreads() function from Xlib before libvlc_new(), and before any call to XOpenDisplay() directly
/// or via any other library.Failure to call XInitThreads() will seriously impede LibVLC performance.
/// Calling XOpenDisplay() before XInitThreads() will eventually crash the process. That is a limitation of Xlib.
/// uint: X11 window ID
///
public uint XWindow
{
get => Native.LibVLCMediaPlayerGetXwindow(NativeReference);
set => Native.LibVLCMediaPlayerSetXwindow(NativeReference, value);
}
///
/// Set a Win32/Win64 API window handle (HWND) where the media player
/// should render its video output. If LibVLC was built without
/// Win32/Win64 API output support, then this has no effects.
///
/// Get the Windows API window handle (HWND) previously set
///
public IntPtr Hwnd
{
get => Native.LibVLCMediaPlayerGetHwnd(NativeReference);
set => Native.LibVLCMediaPlayerSetHwnd(NativeReference, value);
}
#endif
///
/// The movie length (in ms), or -1 if there is no media.
///
public long Length => Native.LibVLCMediaPlayerGetLength(NativeReference);
///
/// Set the movie time (in ms). This has no effect if no media is being
/// played. Not all formats and protocols support this.
///
/// Get the movie time (in ms), or -1 if there is no media.
///
public long Time
{
get => Native.LibVLCMediaPlayerGetTime(NativeReference);
set => Native.LibVLCMediaPlayerSetTime(NativeReference, value);
}
///
/// Set movie position as percentage between 0.0 and 1.0. This has no
/// effect if playback is not enabled. This might not work depending on
/// the underlying input format and protocol.
///
/// Get movie position as percentage between 0.0 and 1.0.
///
public float Position
{
get => Native.LibVLCMediaPlayerGetPosition(NativeReference);
set => Native.LibVLCMediaPlayerSetPosition(NativeReference, value);
}
///
/// Set movie chapter (if applicable).
///
/// Get the movie chapter number currently playing, or -1 if there is no media.
///
public int Chapter
{
get => Native.LibVLCMediaPlayerGetChapter(NativeReference);
set => Native.LibVLCMediaPlayerSetChapter(NativeReference, value);
}
///
/// Get the number of chapters in movie, or -1.
///
public int ChapterCount => Native.LibVLCMediaPlayerGetChapterCount(NativeReference);
///
/// True if the player is able to play
///
public bool WillPlay => Native.LibVLCMediaPlayerWillPlay(NativeReference) != 0;
///
/// Get the number of chapters in title, or -1
///
///
///
public int ChapterCountForTitle(int title) => Native.LibVLCMediaPlayerGetChapterCountForTitle(NativeReference, title);
///
/// Set movie title number to play
///
/// Get movie title number currently playing, or -1
///
public int Title
{
get => Native.LibVLCMediaPlayerGetTitle(NativeReference);
set => Native.LibVLCMediaPlayerSetTitle(NativeReference, value);
}
///
/// The title number count, or -1
///
public int TitleCount => Native.LibVLCMediaPlayerGetTitleCount(NativeReference);
///
/// Set previous chapter (if applicable)
///
public void PreviousChapter()
{
Native.LibVLCMediaPlayerPreviousChapter(NativeReference);
}
///
/// Set next chapter (if applicable)
///
public void NextChapter()
{
Native.LibVLCMediaPlayerNextChapter(NativeReference);
}
///
/// Get the requested movie play rate.
/// warning
///
/// Depending on the underlying media, the requested rate may be
/// different from the real playback rate.
///
public float Rate => Native.LibVLCMediaPlayerGetRate(NativeReference);
///
/// Set movie play rate
///
/// movie play rate to set
///
/// return -1 if an error was detected, 0 otherwise (but even then, it
/// might not actually work depending on the underlying media protocol)
///
public int SetRate(float rate)
{
return Native.LibVLCMediaPlayerSetRate(NativeReference, rate);
}
///
/// Get the current state of the media player (playing, paused, ...)
///
public VLCState State => Native.LibVLCMediaPlayerGetState(NativeReference);
///
/// Get the frames per second (fps) for this playing movie, or 0 if unspecified
///
public float Fps => Native.LibVLCMediaPlayerGetFps(NativeReference);
///
/// Get the number of video outputs
///
public uint VoutCount => Native.LibVLCMediaPlayerHasVout(NativeReference);
///
/// True if the media player can seek
///
public bool IsSeekable => Native.LibVLCMediaPlayerIsSeekable(NativeReference) != 0;
///
/// True if the media player can pause
///
public bool CanPause => Native.LibVLCMediaPlayerCanPause(NativeReference) != 0;
///
/// True if the current program is scrambled
///
/// LibVLC 2.2.0 or later
///
public bool ProgramScambled => Native.LibVLCMediaPlayerProgramScrambled(NativeReference) != 0;
///
/// Display the next frame (if supported)
///
public void NextFrame()
{
Native.LibVLCMediaPlayerNextFrame(NativeReference);
}
///
/// Navigate through DVD Menu
///
/// the Navigation mode
/// LibVLC 2.0.0 or later
public void Navigate(uint navigate)
{
Native.LibVLCMediaPlayerNavigate(NativeReference, navigate);
}
///
/// Set if, and how, the video title will be shown when media is played.
///
/// position at which to display the title, or libvlc_position_disable to prevent the title from being displayed
/// title display timeout in milliseconds (ignored if libvlc_position_disable)
/// LibVLC 2.1.0 or later
public void SetVideoTitleDisplay(Position position, uint timeout)
{
Native.LibVLCMediaPlayerSetVideoTitleDisplay(NativeReference, position, timeout);
}
///
/// Toggle fullscreen status on non-embedded video outputs.
///
/// warning: The same limitations applies to this function as to MediaPlayer::setFullscreen()
///
public void ToggleFullscreen()
{
Native.LibVLCToggleFullscreen(NativeReference);
}
///
/// Enable or disable fullscreen.
/// Warning, TL;DR version : Unless you know what you're doing, don't use this.
/// Put your VideoView inside a fullscreen control instead, refer to your platform documentation.
///
/// Warning, long version :
/// With most window managers, only a top-level windows can be in full-screen mode.
/// Hence, this function will not operate properly if libvlc_media_player_set_xwindow() was used to embed the video in a non-top-level window.
/// In that case, the embedding window must be reparented to the root window before fullscreen mode is enabled.
/// You will want to reparent it back to its normal parent when disabling fullscreen.
///
/// return the fullscreen status (boolean)
///
public bool Fullscreen
{
get => Native.LibVLCGetFullscreen(NativeReference) != 0;
set => Native.LibVLCSetFullscreen(NativeReference, value ? 1 : 0);
}
///
/// Toggle teletext transparent status on video output.
///
public void ToggleTeletext() => Native.LibVLCToggleTeletext(NativeReference);
///
/// Apply new equalizer settings to a media player.
/// The equalizer is first created by invoking libvlc_audio_equalizer_new() or libvlc_audio_equalizer_new_from_preset().
/// It is possible to apply new equalizer settings to a media player whether the media player is currently playing media or not.
/// Invoking this method will immediately apply the new equalizer settings to the audio output of the currently playing media if there is any.
/// If there is no currently playing media, the new equalizer settings will be applied later if and when new media is played.
/// Equalizer settings will automatically be applied to subsequently played media.
/// To disable the equalizer for a media player invoke this method passing NULL for the p_equalizer parameter.
/// The media player does not keep a reference to the supplied equalizer so it is safe for an application to release the equalizer reference
/// any time after this method returns.
///
/// opaque equalizer handle, or NULL to disable the equalizer for this media player
/// LibVLC 2.2.0 or later
/// true on success, false otherwise.
public bool SetEqualizer(Equalizer equalizer) => Native.LibVLCMediaPlayerSetEqualizer(NativeReference, equalizer.NativeReference) == 0;
///
/// unsetEqualizer disable equalizer for this media player
///
/// true on success, false otherwise.
public bool UnsetEqualizer() => Native.LibVLCMediaPlayerSetEqualizer(NativeReference, IntPtr.Zero) == 0;
LibVLCAudioPlayCb? _audioPlayCb;
LibVLCAudioPauseCb? _audioPauseCb;
LibVLCAudioResumeCb? _audioResumeCb;
LibVLCAudioFlushCb? _audioFlushCb;
LibVLCAudioDrainCb? _audioDrainCb;
IntPtr _audioUserData = IntPtr.Zero;
///
/// Sets callbacks and private data for decoded audio.
/// Use libvlc_audio_set_format() or libvlc_audio_set_format_callbacks() to configure the decoded audio format.
/// Note: The audio callbacks override any other audio output mechanism. If the callbacks are set, LibVLC will not output audio in any way.
///
/// callback to play audio samples (must not be NULL)
/// callback to pause playback (or NULL to ignore)
/// callback to resume playback (or NULL to ignore)
/// callback to flush audio buffers (or NULL to ignore)
/// callback to drain audio buffers (or NULL to ignore)
public void SetAudioCallbacks(LibVLCAudioPlayCb playCb, LibVLCAudioPauseCb? pauseCb,
LibVLCAudioResumeCb? resumeCb, LibVLCAudioFlushCb? flushCb,
LibVLCAudioDrainCb? drainCb)
{
_audioPlayCb = playCb ?? throw new ArgumentNullException(nameof(playCb));
_audioPauseCb = pauseCb;
_audioResumeCb = resumeCb;
_audioFlushCb = flushCb;
_audioDrainCb = drainCb;
Native.LibVLCAudioSetCallbacks(
NativeReference,
AudioPlayCallbackHandle,
(pauseCb == null) ? null : AudioPauseCallbackHandle,
(resumeCb == null) ? null : AudioResumeCallbackHandle,
(flushCb == null) ? null : AudioFlushCallbackHandle,
(drainCb == null) ? null : AudioDrainCallbackHandle,
GCHandle.ToIntPtr(_gcHandle));
}
LibVLCVolumeCb? _audioVolumeCb;
///
/// Set callbacks and private data for decoded audio.
/// This only works in combination with libvlc_audio_set_callbacks().
/// Use libvlc_audio_set_format() or libvlc_audio_set_format_callbacks() to configure the decoded audio format.
///
/// callback to apply audio volume, or NULL to apply volume in software
public void SetVolumeCallback(LibVLCVolumeCb volumeCb)
{
_audioVolumeCb = volumeCb;
Native.LibVLCAudioSetVolumeCallback(NativeReference, (volumeCb == null) ? null : AudioVolumeCallbackHandle);
}
LibVLCAudioSetupCb? _setupCb;
LibVLCAudioCleanupCb? _cleanupCb;
///
/// Sets decoded audio format via callbacks.
/// This only works in combination with libvlc_audio_set_callbacks().
///
/// callback to select the audio format (cannot be NULL)
/// callback to release any allocated resources (or NULL)
public void SetAudioFormatCallback(LibVLCAudioSetupCb setupCb, LibVLCAudioCleanupCb cleanupCb)
{
_setupCb = setupCb ?? throw new ArgumentNullException(nameof(setupCb));
_cleanupCb = cleanupCb;
Native.LibVLCAudioSetFormatCallbacks(NativeReference, AudioSetupCallbackHandle, (cleanupCb == null) ? null : AudioCleanupCallbackHandle);
}
///
/// Sets a fixed decoded audio format.
/// This only works in combination with libvlc_audio_set_callbacks(), and is mutually exclusive with libvlc_audio_set_format_callbacks().
///
/// a four-characters string identifying the sample format (e.g. "S16N" or "FL32")
/// sample rate (expressed in Hz)
/// channels count
public void SetAudioFormat(string format, uint rate, uint channels)
{
var formatUtf8 = format.ToUtf8();
MarshalUtils.PerformInteropAndFree(() => Native.LibVLCAudioSetFormat(NativeReference, formatUtf8, rate, channels), formatUtf8);
}
///
/// Selects an audio output module.
/// Note:
/// Any change will take effect only after playback is stopped and restarted. Audio output cannot be changed while playing.
///
/// name of audio output, use psz_name of
/// true if function succeeded, false on error
public bool SetAudioOutput(string name)
{
var nameUtf8 = name.ToUtf8();
return MarshalUtils.PerformInteropAndFree(() => Native.LibVLCAudioOutputSet(NativeReference, nameUtf8), nameUtf8) == 0;
}
///
/// Get the current audio output device identifier.
/// This complements
/// warning The initial value for the current audio output device identifier
/// may not be set or may be some unknown value.A LibVLC application should
/// compare this value against the known device identifiers (e.g.those that
/// were previously retrieved by a call to or
/// ) to find the current audio output device.
///
/// It is possible that the selected audio output device changes(an external
/// change) without a call to .That may make this
/// method unsuitable to use if a LibVLC application is attempting to track
/// dynamic audio device changes as they happen.
///
///
/// the current audio output device identifier, or NULL if no device is selected or in case of error.
public string? OutputDevice => Native.LibVLCAudioOutputDeviceGet(NativeReference).FromUtf8(libvlcFree: true);
///
/// Configures an explicit audio output device.
/// If the module paramater is NULL, audio output will be moved to the device
/// specified by the device identifier string immediately.This is the
/// recommended usage.
/// A list of adequate potential device strings can be obtained with
///
/// However passing NULL is supported in LibVLC version 2.2.0 and later only;
/// in earlier versions, this function would have no effects when the module
/// parameter was NULL.
/// If the module parameter is not NULL, the device parameter of the
/// corresponding audio output, if it exists, will be set to the specified
/// string.
/// A list of adequate potential device strings can be obtained with
///
///
/// device identifier string
/// If NULL, current audio output module. if non-NULL, name of audio output module
public void SetOutputDevice(string deviceId, string? module = null)
{
var deviceIdUtf8 = deviceId.ToUtf8();
var moduleUtf8 = module.ToUtf8();
MarshalUtils.PerformInteropAndFree(() =>
Native.LibVLCAudioOutputDeviceSet(NativeReference, moduleUtf8, deviceIdUtf8),
moduleUtf8, deviceIdUtf8);
}
///
/// Gets a list of potential audio output devices
/// Not all audio outputs support enumerating devices. The audio output may be functional even if the list is empty (NULL).
/// The list may not be exhaustive. Some audio output devices in the list might not actually work in some circumstances.
/// By default, it is recommended to not specify any explicit audio device.
///
public AudioOutputDevice[] AudioOutputDeviceEnum =>
MarshalUtils.Retrieve(() => Native.LibVLCAudioOutputDeviceEnum(NativeReference),
MarshalUtils.PtrToStructure,
s => s.Build(),
device => device.Next,
Native.LibVLCAudioOutputDeviceListRelease);
///
/// Toggle mute status.
/// Warning
/// Toggling mute atomically is not always possible: On some platforms, other processes can mute the VLC audio playback
/// stream asynchronously.
/// Thus, there is a small race condition where toggling will not work.
/// See also the limitations of libvlc_audio_set_mute().
///
public void ToggleMute() => Native.LibVLCAudioToggleMute(NativeReference);
///
/// Get current mute status.
/// Set mute status.
/// Warning
/// This function does not always work.
/// If there are no active audio playback stream, the mute status might not be available.
/// If digital pass-through (S/PDIF, HDMI...) is in use, muting may be unapplicable.
/// Also some audio output plugins do not support muting at all.
/// Note
/// To force silent playback, disable all audio tracks. This is more efficient and reliable than mute.
///
public bool Mute
{
get => Native.LibVLCAudioGetMute(NativeReference) == 1;
set => Native.LibVLCAudioSetMute(NativeReference, value ? 1 : 0);
}
///
/// Get/Set the volume in percents (0 = mute, 100 = 0dB)
///
public int Volume
{
get => Native.LibVLCAudioGetVolume(NativeReference);
set => Native.LibVLCAudioSetVolume(NativeReference, value);
}
///
/// Get the number of available audio tracks (int), or -1 if unavailable
///
public int AudioTrackCount => Native.LibVLCAudioGetTrackCount(NativeReference);
///
/// Retrive the audio track description
///
public TrackDescription[] AudioTrackDescription => MarshalUtils.Retrieve(() => Native.LibVLCAudioGetTrackDescription(NativeReference),
MarshalUtils.PtrToStructure,
t => t.Build(),
t => t.Next,
Native.LibVLCTrackDescriptionListRelease);
///
/// Get current audio track ID or -1 if no active input.
///
public int AudioTrack => Native.LibVLCAudioGetTrack(NativeReference);
///
/// Set current audio track.
///
/// the track ID (i_id field from track description)
/// 0 on success, -1 on error
public bool SetAudioTrack(int trackIndex) => Native.LibVLCAudioSetTrack(NativeReference, trackIndex) == 0;
///
/// Get current audio channel.
///
public AudioOutputChannel Channel => Native.LibVLCAudioGetChannel(NativeReference);
///
/// Set current audio channel.
///
/// the audio channel
///
public bool SetChannel(AudioOutputChannel channel) => Native.LibVLCAudioSetChannel(NativeReference, channel) == 0;
///
/// Equals override based on the native instance reference
///
/// the mediaplayer instance to compare this to
///
public override bool Equals(object obj)
{
return obj is MediaPlayer player &&
EqualityComparer.Default.Equals(NativeReference, player.NativeReference);
}
///
/// Custom hascode implemenation for this MediaPlayer instance
///
/// the hashcode for this MediaPlayer instance
public override int GetHashCode()
{
return NativeReference.GetHashCode();
}
///
/// Get current audio delay (microseconds).
///
public long AudioDelay => Native.LibVLCAudioGetDelay(NativeReference);
///
/// Set current audio delay. The audio delay will be reset to zero each
/// time the media changes.
///
/// the audio delay (microseconds)
/// true on success, false on error
public bool SetAudioDelay(long delay) => Native.LibVLCAudioSetDelay(NativeReference, delay) == 0;
LibVLCVideoLockCb? _videoLockCb;
LibVLCVideoUnlockCb? _videoUnlockCb;
LibVLCVideoDisplayCb? _videoDisplayCb;
///
/// Set callbacks and private data to render decoded video to a custom area in memory.
/// Use libvlc_video_set_format() or libvlc_video_set_format_callbacks() to configure the decoded format.
/// Warning
/// Rendering video into custom memory buffers is considerably less efficient than rendering in a custom window as normal.
/// For optimal perfomances, VLC media player renders into a custom window, and does not use this function and associated callbacks.
/// It is highly recommended that other LibVLC-based application do likewise.
/// To embed video in a window, use libvlc_media_player_set_xid() or equivalent depending on the operating system.
/// If window embedding does not fit the application use case, then a custom LibVLC video output display plugin is required to maintain optimal video rendering performances.
/// The following limitations affect performance:
/// Hardware video decoding acceleration will either be disabled completely, or require(relatively slow) copy from video/DSP memory to main memory.
/// Sub-pictures(subtitles, on-screen display, etc.) must be blent into the main picture by the CPU instead of the GPU.
/// Depending on the video format, pixel format conversion, picture scaling, cropping and/or picture re-orientation,
/// must be performed by the CPU instead of the GPU.
/// Memory copying is required between LibVLC reference picture buffers and application buffers (between lock and unlock callbacks).
///
/// callback to lock video memory (must not be NULL)
/// callback to unlock video memory (or NULL if not needed)
/// callback to display video (or NULL if not needed)
public void SetVideoCallbacks(LibVLCVideoLockCb lockCb, LibVLCVideoUnlockCb? unlockCb,
LibVLCVideoDisplayCb? displayCb)
{
_videoLockCb = lockCb ?? throw new ArgumentNullException(nameof(lockCb));
_videoUnlockCb = unlockCb;
_videoDisplayCb = displayCb;
Native.LibVLCVideoSetCallbacks(NativeReference,
VideoLockCallbackHandle,
(unlockCb == null)? null : VideoUnlockCallbackHandle,
(displayCb == null)? null : VideoDisplayCallbackHandle,
GCHandle.ToIntPtr(_gcHandle));
}
///
/// Set decoded video chroma and dimensions. This only works in
/// combination with MediaPlayer::setCallbacks() , and is mutually exclusive
/// with MediaPlayer::setFormatCallbacks()
///
/// a four-characters string identifying the chroma (e.g."RV32" or "YUYV")
/// pixel width
/// pixel height
/// line pitch (in bytes)
public void SetVideoFormat(string chroma, uint width, uint height, uint pitch)
{
var chromaUtf8 = chroma.ToUtf8();
MarshalUtils.PerformInteropAndFree(() =>
Native.LibVLCVideoSetFormat(NativeReference, chromaUtf8, width, height, pitch),
chromaUtf8);
}
LibVLCVideoFormatCb? _videoFormatCb;
LibVLCVideoCleanupCb? _videoCleanupCb;
IntPtr _videoUserData = IntPtr.Zero;
///
/// Set decoded video chroma and dimensions.
/// This only works in combination with libvlc_video_set_callbacks().
///
/// callback to select the video format (cannot be NULL)
/// callback to release any allocated resources (or NULL)
public void SetVideoFormatCallbacks(LibVLCVideoFormatCb formatCb, LibVLCVideoCleanupCb? cleanupCb)
{
_videoFormatCb = formatCb ?? throw new ArgumentNullException(nameof(formatCb));
_videoCleanupCb = cleanupCb;
Native.LibVLCVideoSetFormatCallbacks(NativeReference, VideoFormatCallbackHandle,
(cleanupCb == null)? null : VideoCleanupCallbackHandle);
}
///
/// Enable or disable key press events handling, according to the LibVLC hotkeys configuration.
/// By default and for historical reasons, keyboard events are handled by the LibVLC video widget.
/// Note
/// On X11, there can be only one subscriber for key press and mouse click events per window.
/// If your application has subscribed to those events for the X window ID of the video widget,
/// then LibVLC will not be able to handle key presses and mouse clicks in any case.
/// Warning
/// This function is only implemented for X11 and Win32 at the moment.
/// true to handle key press events, false to ignore them.
///
public bool EnableKeyInput
{
set => Native.LibVLCVideoSetKeyInput(NativeReference, value ? 1 : 0);
}
///
/// Enable or disable mouse click events handling.
/// By default, those events are handled. This is needed for DVD menus to work, as well as a few video filters such as "puzzle".
/// Warning
/// This function is only implemented for X11 and Win32 at the moment.
/// true to handle mouse click events, false to ignore them.
///
public bool EnableMouseInput
{
set => Native.LibVLCVideoSetMouseInput(NativeReference, value ? 1 : 0);
}
///
/// Get the pixel dimensions of a video.
///
/// number of the video (starting from, and most commonly 0)
/// pointer to get the pixel width [OUT]
/// pointer to get the pixel height [OUT]
///
public bool Size(uint num, ref uint px, ref uint py)
{
return Native.LibVLCVideoGetSize(NativeReference, num, ref px, ref py) == 0;
}
///
/// Get the mouse pointer coordinates over a video.
/// Coordinates are expressed in terms of the decoded video resolution, not in terms of pixels on the screen/viewport
/// (to get the latter, you can query your windowing system directly).
/// Either of the coordinates may be negative or larger than the corresponding dimension of the video,
/// if the cursor is outside the rendering area.
/// Warning
/// The coordinates may be out-of-date if the pointer is not located on the video rendering area.
/// LibVLC does not track the pointer if it is outside of the video widget.
/// Note
/// LibVLC does not support multiple pointers(it does of course support multiple input devices sharing the same pointer) at the moment.
///
/// number of the video (starting from, and most commonly 0)
/// pointer to get the abscissa [OUT]
/// pointer to get the ordinate [OUT]
/// true on success, false on failure
public bool Cursor(uint num, ref int px, ref int py)
{
return Native.LibVLCVideoGetCursor(NativeReference, num, ref px, ref py) == 0;
}
///
/// Get/Set the current video scaling factor. See also MediaPlayer::setScale() .
/// That is the ratio of the number of
/// pixels on screen to the number of pixels in the original decoded video
/// in each dimension.Zero is a special value; it will adjust the video
/// to the output window/drawable(in windowed mode) or the entire screen.
/// Note that not all video outputs support scaling.
///
public float Scale
{
get => Native.LibVLCVideoGetScale(NativeReference);
set => Native.LibVLCVideoSetScale(NativeReference, value);
}
///
/// Get/set current video aspect ratio.
/// Set to null to reset to default
/// Invalid aspect ratios are ignored.
///
public string? AspectRatio
{
get => Native.LibVLCVideoGetAspectRatio(NativeReference).FromUtf8(libvlcFree: true);
set
{
var aspectRatioUtf8 = value.ToUtf8();
MarshalUtils.PerformInteropAndFree(() => Native.LibVLCVideoSetAspectRatio(NativeReference, aspectRatioUtf8), aspectRatioUtf8);
}
}
///
/// The current video subtitle track
///
public int Spu => Native.LibVLCVideoGetSpu(NativeReference);
///
/// Set Spu (subtitle)
///
/// Video subtitle track to select (id from track description)
/// true on success, false otherwise
public bool SetSpu(int spu) => Native.LibVLCVideoSetSpu(NativeReference, spu) == 0;
///
/// Get the number of available video subtitles.
///
public int SpuCount => Native.LibVLCVideoGetSpuCount(NativeReference);
///
/// Retrieve SpuDescription in a TrackDescription struct
///
public TrackDescription[] SpuDescription => MarshalUtils.Retrieve(() => Native.LibVLCVideoGetSpuDescription(NativeReference),
MarshalUtils.PtrToStructure,
t => t.Build(),
t => t.Next,
Native.LibVLCTrackDescriptionListRelease);
///
/// Get the current subtitle delay.
///
public long SpuDelay => Native.LibVLCVideoGetSpuDelay(NativeReference);
///
/// Set the subtitle delay.
/// This affects the timing of when the subtitle will be displayed.
/// Positive values result in subtitles being displayed later, while negative values will result in subtitles being displayed earlier.
/// The subtitle delay will be reset to zero each time the media changes.
///
/// time (in microseconds) the display of subtitles should be delayed
/// true if successful, false otherwise
public bool SetSpuDelay(long delay) => Native.LibVLCVideoSetSpuDelay(NativeReference, delay) == 0;
///
/// Get the description of available titles.
///
public TrackDescription[] TitleDescription => MarshalUtils.Retrieve(() => Native.LibVLCVideoGetTitleDescription(NativeReference),
MarshalUtils.PtrToStructure,
t => t.Build(),
t => t.Next,
Native.LibVLCTrackDescriptionListRelease);
///
/// Get the full description of available chapters.
///
/// Index of the title to query for chapters (uses current title if set to -1)
/// Array of chapter descriptions.
public ChapterDescription[] FullChapterDescriptions(int titleIndex = -1) => MarshalUtils.Retrieve(NativeReference,
(IntPtr nativeRef, out IntPtr array) =>
{
var count = Native.LibVLCMediaPlayerGetFullChapterDescriptions(nativeRef, titleIndex, out array);
// the number of chapters (-1 on error)
return count < 0 ? 0 : (uint)count;
},
MarshalUtils.PtrToStructure,
t => t.Build(),
Native.LibVLCChapterDescriptionsRelease);
///
/// Get the description of available chapters for specific title.
///
/// selected title
/// chapter descriptions
public TrackDescription[] ChapterDescription(int titleIndex) => MarshalUtils.Retrieve(() => Native.LibVLCVideoGetChapterDescription(NativeReference, titleIndex),
MarshalUtils.PtrToStructure,
t => t.Build(),
t => t.Next,
Native.LibVLCTrackDescriptionListRelease);
///
/// Get/Set current crop filter geometry.
/// Empty string to unset
///
public string? CropGeometry
{
get => Native.LibVLCVideoGetCropGeometry(NativeReference).FromUtf8(libvlcFree: true);
set
{
var cropGeometryUtf8 = value.ToUtf8();
MarshalUtils.PerformInteropAndFree(() => Native.LibVLCVideoSetCropGeometry(NativeReference, cropGeometryUtf8), cropGeometryUtf8);
}
}
///
/// Get current teletext page requested.
/// Set new teletext page to retrieve.
///
public int Teletext
{
get => Native.LibVLCVideoGetTeletext(NativeReference);
set => Native.LibVLCVideoSetTeletext(NativeReference, value);
}
///
/// Get number of available video tracks.
///
public int VideoTrackCount => Native.LibVLCVideoGetTrackCount(NativeReference);
///
/// Get the description of available video tracks.
///
public TrackDescription[] VideoTrackDescription => MarshalUtils.Retrieve(() => Native.LibVLCVideoGetTrackDescription(NativeReference),
MarshalUtils.PtrToStructure,
t => t.Build(),
t => t.Next,
Native.LibVLCTrackDescriptionListRelease);
///
/// Get current video track ID (int) or -1 if no active input.
///
public int VideoTrack => Native.LibVLCVideoGetTrack(NativeReference);
///
/// Set video track.
///
/// the track ID (i_id field from track description)
/// true on sucess, false out of range
public bool SetVideoTrack(int trackIndex) => Native.LibVLCVideoSetTrack(NativeReference, trackIndex) == 0;
///
/// Take a snapshot of the current video window.
/// If i_width AND i_height is 0, original size is used. If i_width XOR
/// i_height is 0, original aspect-ratio is preserved.
///
/// number of video output (typically 0 for the first/only one)
/// the path where to save the screenshot to
/// the snapshot's width
/// the snapshot's height
/// true on success
public bool TakeSnapshot(uint num, string? filePath, uint width, uint height)
{
var filePathUtf8 = filePath.ToUtf8();
return MarshalUtils.PerformInteropAndFree(() =>
Native.LibVLCVideoTakeSnapshot(NativeReference, num, filePathUtf8, width, height) == 0,
filePathUtf8);
}
///
/// Enable or disable deinterlace filter
///
/// type of deinterlace filter, null to disable
public void SetDeinterlace(string? deinterlaceMode)
{
var deinterlaceModeUtf8 = deinterlaceMode.ToUtf8();
MarshalUtils.PerformInteropAndFree(() =>
Native.LibVLCVideoSetDeinterlace(NativeReference, deinterlaceModeUtf8),
deinterlaceModeUtf8);
}
///
/// Get an integer marquee option value
///
/// marq option to get
///
public int MarqueeInt(VideoMarqueeOption option) => Native.LibVLCVideoGetMarqueeInt(NativeReference, option);
///
/// Get a string marquee option value
///
/// marq option to get
///
public string? MarqueeString(VideoMarqueeOption option)
{
var marqueeStrPtr = Native.LibVLCVideoGetMarqueeString(NativeReference, option);
return marqueeStrPtr.FromUtf8(libvlcFree: true);
}
///
/// Enable, disable or set an integer marquee option
/// Setting libvlc_marquee_Enable has the side effect of enabling (arg !0)
/// or disabling (arg 0) the marq filter.
///
/// marq option to set
/// marq option value
public void SetMarqueeInt(VideoMarqueeOption option, int value) =>
Native.LibVLCVideoSetMarqueeInt(NativeReference, option, value);
///
/// Enable, disable or set an string marquee option
///
/// marq option to set
/// marq option value
public void SetMarqueeString(VideoMarqueeOption option, string? marqueeValue)
{
var marqueeValueUtf8 = marqueeValue.ToUtf8();
MarshalUtils.PerformInteropAndFree(() =>
Native.LibVLCVideoSetMarqueeString(NativeReference, option, marqueeValueUtf8),
marqueeValueUtf8);
}
///
/// Get integer logo option.
///
/// logo option to get, values of libvlc_video_logo_option_t
///
public int LogoInt(VideoLogoOption option) => Native.LibVLCVideoGetLogoInt(NativeReference, option);
///
/// Set logo option as integer. Options that take a different type value
/// are ignored. Passing libvlc_logo_enable as option value has the side
/// effect of starting (arg !0) or stopping (arg 0) the logo filter.
///
/// logo option to set, values of libvlc_video_logo_option_t
/// logo option value
public void SetLogoInt(VideoLogoOption option, int value) => Native.LibVLCVideoSetLogoInt(NativeReference, option, value);
///
/// Set logo option as string. Options that take a different type value are ignored.
///
/// logo option to set, values of libvlc_video_logo_option_t
/// logo option value
public void SetLogoString(VideoLogoOption option, string? logoValue)
{
var logoValueUtf8 = logoValue.ToUtf8();
MarshalUtils.PerformInteropAndFree(() =>
Native.LibVLCVideoSetLogoString(NativeReference, option, logoValueUtf8),
logoValueUtf8);
}
///
/// Get integer adjust option.
///
/// adjust option to get, values of libvlc_video_adjust_option_t
///
public int AdjustInt(VideoAdjustOption option) => Native.LibVLCVideoGetAdjustInt(NativeReference, option);
///
/// Set adjust option as integer. Options that take a different type value
/// are ignored. Passing libvlc_adjust_enable as option value has the side
/// effect of starting (arg !0) or stopping (arg 0) the adjust filter.
///
/// adust option to set, values of libvlc_video_adjust_option_t
/// adjust option value
public void SetAdjustInt(VideoAdjustOption option, int value) => Native.LibVLCVideoSetAdjustInt(NativeReference, option, value);
///
/// Get adjust option float value
///
/// The option for which to get the value
/// the float value for a given option
public float AdjustFloat(VideoAdjustOption option) => Native.LibVLCVideoGetAdjustFloat(NativeReference, option);
///
/// Set adjust option as float. Options that take a different type value are ignored.
///
/// adust option to set, values of
/// adjust option value
public void SetAdjustFloat(VideoAdjustOption option, float value) => Native.LibVLCVideoSetAdjustFloat(NativeReference, option, value);
#if ANDROID
///
/// Set the android context.
///
/// See LibVLCSharp.Android
public void SetAndroidContext(IntPtr aWindow) => Native.LibVLCMediaPlayerSetAndroidContext(NativeReference, aWindow);
#endif
///
/// Add a slave to the current media player.
/// note If the player is playing, the slave will be added directly. This call
/// will also update the slave list of the attached VLC::Media.
///
/// subtitle or audio
/// Uri of the slave (should contain a valid scheme).
/// True if this slave should be selected when it's loaded
///
public bool AddSlave(MediaSlaveType type, string uri, bool select)
{
var uriUtf8 = uri.ToUtf8();
return MarshalUtils.PerformInteropAndFree(() =>
Native.LibVLCMediaPlayerAddSlave(NativeReference, type, uriUtf8, select) == 0,
uriUtf8);
}
///
/// Current 360 viewpoint of this mediaplayer.
/// Update with
///
public VideoViewpoint Viewpoint { get; private set; }
///
/// Update the video viewpoint information.
/// The values are set asynchronously, it will be used by the next frame displayed.
/// It is safe to call this function before the media player is started.
/// LibVLC 3.0.0 and later
///
/// view point yaw in degrees ]-180;180]
/// view point pitch in degrees ]-90;90]
/// view point roll in degrees ]-180;180]
/// field of view in degrees ]0;180[ (default 80.)
/// if true replace the old viewpoint with the new one. If false, increase/decrease it.
/// true if successful, false otherwise
public bool UpdateViewpoint(float yaw, float pitch, float roll, float fov, bool absolute = true)
{
var vpPtr = Native.LibVLCVideoNewViewpoint();
if (vpPtr == IntPtr.Zero) return false;
Viewpoint = new VideoViewpoint(yaw, pitch, roll, fov);
Marshal.StructureToPtr(Viewpoint, vpPtr, false);
var result = Native.LibVLCVideoUpdateViewpoint(NativeReference, vpPtr, absolute) == 0;
MarshalUtils.LibVLCFree(ref vpPtr);
return result;
}
///
/// Set a renderer to the media player.
///
/// discovered renderer item or null to fallback on local rendering
/// true on success, false otherwise
public bool SetRenderer(RendererItem? rendererItem) =>
Native.LibVLCMediaPlayerSetRenderer(NativeReference, rendererItem?.NativeReference ?? IntPtr.Zero) == 0;
/// Gets the media role.
/// version LibVLC 3.0.0 and later.
///
public MediaPlayerRole Role => Native.LibVLCMediaPlayerGetRole(NativeReference);
/// Sets the media role.
/// version LibVLC 3.0.0 and later.
///
/// true on success, false otherwise
public bool SetRole(MediaPlayerRole role) => Native.LibVLCMediaPlayerSetRole(NativeReference, role) == 0;
/// Increments the native reference counter for this mediaplayer instance
internal void Retain() => Native.LibVLCMediaPlayerRetain(NativeReference);
///
/// Enable/disable hardware decoding in a crossplatform way.
///
public bool EnableHardwareDecoding
{
get => Configuration.EnableHardwareDecoding;
set => Configuration.EnableHardwareDecoding = value;
}
///
/// Caching value for local files, in milliseconds [0 .. 60000ms]
///
public uint FileCaching
{
get => Configuration.FileCaching;
set => Configuration.FileCaching = value;
}
///
/// Caching value for network resources, in milliseconds [0 .. 60000ms]
///
public uint NetworkCaching
{
get => Configuration.NetworkCaching;
set => Configuration.NetworkCaching = value;
}
MediaConfiguration Configuration = new MediaConfiguration();
#region Callbacks
static readonly LibVLCVideoLockCb VideoLockCallbackHandle = VideoLockCallback;
static readonly LibVLCVideoUnlockCb VideoUnlockCallbackHandle = VideoUnlockCallback;
static readonly LibVLCVideoDisplayCb VideoDisplayCallbackHandle = VideoDisplayCallback;
static readonly LibVLCVideoFormatCb VideoFormatCallbackHandle = VideoFormatCallback;
static readonly LibVLCVideoCleanupCb VideoCleanupCallbackHandle = VideoCleanupCallback;
[MonoPInvokeCallback(typeof(LibVLCVideoLockCb))]
private static IntPtr VideoLockCallback(IntPtr opaque, IntPtr planes)
{
var mediaPlayer = MarshalUtils.GetInstance(opaque);
if (mediaPlayer?._videoLockCb != null)
{
return mediaPlayer._videoLockCb(mediaPlayer._videoUserData, planes);
}
return IntPtr.Zero;
}
[MonoPInvokeCallback(typeof(LibVLCVideoUnlockCb))]
private static void VideoUnlockCallback(IntPtr opaque, IntPtr picture, IntPtr planes)
{
var mediaPlayer = MarshalUtils.GetInstance(opaque);
if (mediaPlayer?._videoUnlockCb != null)
{
mediaPlayer._videoUnlockCb(mediaPlayer._videoUserData, picture, planes);
}
}
[MonoPInvokeCallback(typeof(LibVLCVideoDisplayCb))]
private static void VideoDisplayCallback(IntPtr opaque, IntPtr picture)
{
var mediaPlayer = MarshalUtils.GetInstance(opaque);
if (mediaPlayer?._videoDisplayCb != null)
{
mediaPlayer._videoDisplayCb(mediaPlayer._videoUserData, picture);
}
}
[MonoPInvokeCallback(typeof(LibVLCVideoFormatCb))]
private static uint VideoFormatCallback(ref IntPtr opaque, IntPtr chroma, ref uint width, ref uint height, ref uint pitches, ref uint lines)
{
var mediaPlayer = MarshalUtils.GetInstance(opaque);
if (mediaPlayer?._videoFormatCb != null)
{
return mediaPlayer._videoFormatCb(ref mediaPlayer._videoUserData, chroma, ref width, ref height, ref pitches, ref lines);
}
return 0;
}
[MonoPInvokeCallback(typeof(LibVLCVideoCleanupCb))]
private static void VideoCleanupCallback(ref IntPtr opaque)
{
var mediaPlayer = MarshalUtils.GetInstance(opaque);
if (mediaPlayer?._videoCleanupCb != null)
{
mediaPlayer._videoCleanupCb(ref mediaPlayer._videoUserData);
}
}
static readonly LibVLCAudioPlayCb AudioPlayCallbackHandle = AudioPlayCallback;
static readonly LibVLCAudioPauseCb AudioPauseCallbackHandle = AudioPauseCallback;
static readonly LibVLCAudioResumeCb AudioResumeCallbackHandle = AudioResumeCallback;
static readonly LibVLCAudioFlushCb AudioFlushCallbackHandle = AudioFlushCallback;
static readonly LibVLCAudioDrainCb AudioDrainCallbackHandle = AudioDrainCallback;
static readonly LibVLCVolumeCb AudioVolumeCallbackHandle = AudioVolumeCallback;
static readonly LibVLCAudioSetupCb AudioSetupCallbackHandle = AudioSetupCallback;
static readonly LibVLCAudioCleanupCb AudioCleanupCallbackHandle = AudioCleanupCallback;
[MonoPInvokeCallback(typeof(LibVLCAudioPlayCb))]
private static void AudioPlayCallback(IntPtr data, IntPtr samples, uint count, long pts)
{
var mediaPlayer = MarshalUtils.GetInstance(data);
if (mediaPlayer?._audioPlayCb != null)
{
mediaPlayer._audioPlayCb(mediaPlayer._audioUserData, samples, count, pts);
}
}
[MonoPInvokeCallback(typeof(LibVLCAudioPauseCb))]
private static void AudioPauseCallback(IntPtr data, long pts)
{
var mediaPlayer = MarshalUtils.GetInstance(data);
if (mediaPlayer?._audioPauseCb != null)
{
mediaPlayer._audioPauseCb(mediaPlayer._audioUserData, pts);
}
}
[MonoPInvokeCallback(typeof(LibVLCAudioResumeCb))]
private static void AudioResumeCallback(IntPtr data, long pts)
{
var mediaPlayer = MarshalUtils.GetInstance(data);
if (mediaPlayer?._audioResumeCb != null)
{
mediaPlayer._audioResumeCb(mediaPlayer._audioUserData, pts);
}
}
[MonoPInvokeCallback(typeof(LibVLCAudioFlushCb))]
private static void AudioFlushCallback(IntPtr data, long pts)
{
var mediaPlayer = MarshalUtils.GetInstance(data);
if (mediaPlayer?._audioFlushCb != null)
{
mediaPlayer._audioFlushCb(mediaPlayer._audioUserData, pts);
}
}
[MonoPInvokeCallback(typeof(LibVLCAudioDrainCb))]
private static void AudioDrainCallback(IntPtr data)
{
var mediaPlayer = MarshalUtils.GetInstance(data);
if (mediaPlayer?._audioDrainCb != null)
{
mediaPlayer._audioDrainCb(mediaPlayer._audioUserData);
}
}
[MonoPInvokeCallback(typeof(LibVLCVolumeCb))]
private static void AudioVolumeCallback(IntPtr data, float volume, bool mute)
{
var mediaPlayer = MarshalUtils.GetInstance(data);
if (mediaPlayer?._audioVolumeCb != null)
{
mediaPlayer._audioVolumeCb(mediaPlayer._audioUserData, volume, mute);
}
}
[MonoPInvokeCallback(typeof(LibVLCAudioSetupCb))]
private static int AudioSetupCallback(ref IntPtr opaque, ref IntPtr format, ref uint rate, ref uint channels)
{
var mediaPlayer = MarshalUtils.GetInstance(opaque);
if (mediaPlayer?._setupCb != null)
{
return mediaPlayer._setupCb(ref mediaPlayer._audioUserData, ref format, ref rate, ref channels);
}
return -1;
}
[MonoPInvokeCallback(typeof(LibVLCAudioCleanupCb))]
private static void AudioCleanupCallback(IntPtr opaque)
{
var mediaPlayer = MarshalUtils.GetInstance(opaque);
if (mediaPlayer?._cleanupCb != null)
{
mediaPlayer._cleanupCb(mediaPlayer._audioUserData);
}
}
///
/// A LibVLC media player plays one media (usually in a custom drawable).
/// @{
///
/// LibVLC simple media player external API
///
/// Opaque equalizer handle.
/// Equalizer settings can be applied to a media player.
/// Callback prototype to allocate and lock a picture buffer.
/// private pointer as passed to libvlc_video_set_callbacks() [IN]
///
/// start address of the pixel planes (LibVLC allocates the array
/// of void pointers, this callback must initialize the array) [OUT]
///
///
/// a private pointer for the display and unlock callbacks to identify
/// the picture buffers
///
///
/// Whenever a new video frame needs to be decoded, the lock callback is
/// invoked. Depending on the video chroma, one or three pixel planes of
/// adequate dimensions must be returned via the second parameter. Those
/// planes must be aligned on 32-bytes boundaries.
///
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate IntPtr LibVLCVideoLockCb(IntPtr opaque, IntPtr planes);
/// Callback prototype to unlock a picture buffer.
/// private pointer as passed to libvlc_video_set_callbacks() [IN]
/// private pointer returned from the
/// pixel planes as defined by the
///
/// When the video frame decoding is complete, the unlock callback is invoked.
/// This callback might not be needed at all. It is only an indication that the
/// application can now read the pixel values if it needs to.
/// A picture buffer is unlocked after the picture is decoded,
/// but before the picture is displayed.
/// callback [IN]
/// callback (this parameter is only for convenience) [IN]
///
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void LibVLCVideoUnlockCb(IntPtr opaque, IntPtr picture, IntPtr planes);
/// Callback prototype to display a picture.
/// private pointer as passed to libvlc_video_set_callbacks() [IN]
/// private pointer returned from the
///
/// When the video frame needs to be shown, as determined by the media playback
/// clock, the display callback is invoked.
/// callback [IN]
///
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void LibVLCVideoDisplayCb(IntPtr opaque, IntPtr picture);
///
/// Callback prototype to configure picture buffers format.
/// This callback gets the format of the video as output by the video decoder
/// and the chain of video filters (if any). It can opt to change any parameter
/// as it needs. In that case, LibVLC will attempt to convert the video format
/// (rescaling and chroma conversion) but these operations can be CPU intensive.
///
///
/// pointer to the private pointer passed to
/// libvlc_video_set_callbacks() [IN/OUT]
///
/// pointer to the 4 bytes video format identifier [IN/OUT]
/// pointer to the pixel width [IN/OUT]
/// pointer to the pixel height [IN/OUT]
///
/// table of scanline pitches in bytes for each pixel plane
/// (the table is allocated by LibVLC) [OUT]
///
/// table of scanlines count for each plane [OUT]
/// the number of picture buffers allocated, 0 indicates failure
///
/// For each pixels plane, the scanline pitch must be bigger than or equal to
/// the number of bytes per pixel multiplied by the pixel width.
/// Similarly, the number of scanlines must be bigger than of equal to
/// the pixel height.
/// Furthermore, we recommend that pitches and lines be multiple of 32
/// to not break assumptions that might be held by optimized code
/// in the video decoders, video filters and/or video converters.
///
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate uint LibVLCVideoFormatCb(ref IntPtr opaque, IntPtr chroma, ref uint width,
ref uint height, ref uint pitches, ref uint lines);
/// Callback prototype to configure picture buffers format.
///
/// private pointer as passed to libvlc_video_set_callbacks()
/// (and possibly modified by
///
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void LibVLCVideoCleanupCb(ref IntPtr opaque);
/// Callback prototype to setup the audio playback.
///
/// pointer to the data pointer passed to
/// libvlc_audio_set_callbacks() [IN/OUT]
///
/// 4 bytes sample format [IN/OUT]
/// sample rate [IN/OUT]
/// channels count [IN/OUT]
/// 0 on success, anything else to skip audio playback
/// This is called when the media player needs to create a new audio output.
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int LibVLCAudioSetupCb(ref IntPtr opaque, ref IntPtr format, ref uint rate, ref uint channels);
/// Callback prototype for audio playback cleanup.
/// data pointer as passed to libvlc_audio_set_callbacks() [IN]
/// This is called when the media player no longer needs an audio output.
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void LibVLCAudioCleanupCb(IntPtr opaque);
/// Callback prototype for audio playback.
/// data pointer as passed to libvlc_audio_set_callbacks() [IN]
/// pointer to a table of audio samples to play back [IN]
/// number of audio samples to play back
/// expected play time stamp (see libvlc_delay())
///
/// The LibVLC media player decodes and post-processes the audio signal
/// asynchronously (in an internal thread). Whenever audio samples are ready
/// to be queued to the output, this callback is invoked.
/// The number of samples provided per invocation may depend on the file format,
/// the audio coding algorithm, the decoder plug-in, the post-processing
/// filters and timing. Application must not assume a certain number of samples.
/// The exact format of audio samples is determined by libvlc_audio_set_format()
/// or libvlc_audio_set_format_callbacks() as is the channels layout.
/// Note that the number of samples is per channel. For instance, if the audio
/// track sampling rate is 48000 Hz, then 1200 samples represent 25 milliseconds
/// of audio signal - regardless of the number of audio channels.
///
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void LibVLCAudioPlayCb(IntPtr data, IntPtr samples, uint count, long pts);
/// Callback prototype for audio pause.
/// data pointer as passed to libvlc_audio_set_callbacks() [IN]
/// time stamp of the pause request (should be elapsed already)
///
/// LibVLC invokes this callback to pause audio playback.
/// The pause callback is never called if the audio is already paused.
///
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void LibVLCAudioPauseCb(IntPtr data, long pts);
/// Callback prototype for audio resumption.
/// data pointer as passed to libvlc_audio_set_callbacks() [IN]
/// time stamp of the resumption request (should be elapsed already)
///
/// LibVLC invokes this callback to resume audio playback after it was
/// previously paused.
/// The resume callback is never called if the audio is not paused.
///
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void LibVLCAudioResumeCb(IntPtr data, long pts);
/// Callback prototype for audio buffer flush.
/// LibVLC invokes this callback if it needs to discard all pending buffers and
/// stop playback as soon as possible. This typically occurs when the media is stopped.
///
/// data pointer as passed to libvlc_audio_set_callbacks() [IN]
/// current presentation timestamp
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void LibVLCAudioFlushCb(IntPtr data, long pts);
/// Callback prototype for audio buffer drain.
/// data pointer as passed to libvlc_audio_set_callbacks() [IN]
///
/// LibVLC may invoke this callback when the decoded audio track is ending.
/// There will be no further decoded samples for the track, but playback should
/// nevertheless continue until all already pending buffers are rendered.
///
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void LibVLCAudioDrainCb(IntPtr data);
/// Callback prototype for audio volume change.
/// data pointer as passed to libvlc_audio_set_callbacks() [IN]
/// software volume (1. = nominal, 0. = mute)
/// muted flag
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void LibVLCVolumeCb(IntPtr data, float volume, [MarshalAs(UnmanagedType.I1)] bool mute);
#endregion
///
/// Get the Event Manager from which the media player send event.
///
MediaPlayerEventManager EventManager
{
get
{
if (_eventManager == null)
{
var eventManagerPtr = Native.LibVLCMediaPlayerEventManager(NativeReference);
_eventManager = new MediaPlayerEventManager(eventManagerPtr);
}
return _eventManager;
}
}
#region events
///
/// The media of this mediaplayer changed
///
public event EventHandler MediaChanged
{
add => EventManager.AttachEvent(EventType.MediaPlayerMediaChanged, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerMediaChanged, value);
}
///
/// Nothing special to report
///
public event EventHandler NothingSpecial
{
add => EventManager.AttachEvent(EventType.MediaPlayerNothingSpecial, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerNothingSpecial, value);
}
///
/// The mediaplayer is opening a media
///
public event EventHandler Opening
{
add => EventManager.AttachEvent(EventType.MediaPlayerOpening, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerOpening, value);
}
///
/// The mediaplayer is buffering
///
public event EventHandler Buffering
{
add => EventManager.AttachEvent(EventType.MediaPlayerBuffering, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerBuffering, value);
}
///
/// The mediaplayer started playing a media
///
public event EventHandler Playing
{
add => EventManager.AttachEvent(EventType.MediaPlayerPlaying, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerPlaying, value);
}
///
/// The mediaplayer paused playback
///
public event EventHandler Paused
{
add => EventManager.AttachEvent(EventType.MediaPlayerPaused, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerPaused, value);
}
///
/// The mediaplayer stopped playback
///
public event EventHandler Stopped
{
add => EventManager.AttachEvent(EventType.MediaPlayerStopped, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerStopped, value);
}
///
/// The mediaplayer went forward in the playback
///
public event EventHandler Forward
{
add => EventManager.AttachEvent(EventType.MediaPlayerForward, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerForward, value);
}
///
/// The mediaplayer went backward in the playback
///
public event EventHandler Backward
{
add => EventManager.AttachEvent(EventType.MediaPlayerBackward, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerBackward, value);
}
///
/// The mediaplayer reached the end of the playback
///
public event EventHandler EndReached
{
add => EventManager.AttachEvent(EventType.MediaPlayerEndReached, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerEndReached, value);
}
///
/// The mediaplayer encountered an error during playback
///
public event EventHandler EncounteredError
{
add => EventManager.AttachEvent(EventType.MediaPlayerEncounteredError, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerEncounteredError, value);
}
///
/// The mediaplayer's playback time changed
///
public event EventHandler TimeChanged
{
add => EventManager.AttachEvent(EventType.MediaPlayerTimeChanged, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerTimeChanged, value);
}
///
/// The mediaplayer's position changed
///
public event EventHandler PositionChanged
{
add => EventManager.AttachEvent(EventType.MediaPlayerPositionChanged, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerPositionChanged, value);
}
///
/// The mediaplayer's seek capability changed
///
public event EventHandler SeekableChanged
{
add => EventManager.AttachEvent(EventType.MediaPlayerSeekableChanged, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerSeekableChanged, value);
}
///
/// The mediaplayer's pause capability changed
///
public event EventHandler PausableChanged
{
add => EventManager.AttachEvent(EventType.MediaPlayerPausableChanged, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerPausableChanged, value);
}
///
/// The title of the mediaplayer changed
///
public event EventHandler TitleChanged
{
add => EventManager.AttachEvent(EventType.MediaPlayerTitleChanged, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerTitleChanged, value);
}
///
/// The mediaplayer changed the chapter of a media
///
public event EventHandler ChapterChanged
{
add => EventManager.AttachEvent(EventType.MediaPlayerChapterChanged, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerChapterChanged, value);
}
///
/// The mediaplayer took a snapshot
///
public event EventHandler SnapshotTaken
{
add => EventManager.AttachEvent(EventType.MediaPlayerSnapshotTaken, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerSnapshotTaken, value);
}
///
/// The length of a playback changed
///
public event EventHandler LengthChanged
{
add => EventManager.AttachEvent(EventType.MediaPlayerLengthChanged, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerLengthChanged, value);
}
///
/// The Video Output count of the MediaPlayer changed
///
public event EventHandler Vout
{
add => EventManager.AttachEvent(EventType.MediaPlayerVout, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerVout, value);
}
///
/// The mediaplayer scrambled status changed
///
public event EventHandler ScrambledChanged
{
add => EventManager.AttachEvent(EventType.MediaPlayerScrambledChanged, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerScrambledChanged, value);
}
///
/// The mediaplayer has a new Elementary Stream (ES)
///
public event EventHandler ESAdded
{
add => EventManager.AttachEvent(EventType.MediaPlayerESAdded, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerESAdded, value);
}
///
/// The mediaplayer has one less Elementary Stream (ES)
///
public event EventHandler ESDeleted
{
add => EventManager.AttachEvent(EventType.MediaPlayerESDeleted, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerESDeleted, value);
}
///
/// An Elementary Stream (ES) was selected
///
public event EventHandler ESSelected
{
add => EventManager.AttachEvent(EventType.MediaPlayerESSelected, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerESSelected, value);
}
///
/// The mediaplayer's audio device changed
///
public event EventHandler AudioDevice
{
add => EventManager.AttachEvent(EventType.MediaPlayerAudioDevice, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerAudioDevice, value);
}
///
/// The mediaplayer is corked
///
public event EventHandler Corked
{
add => EventManager.AttachEvent(EventType.MediaPlayerCorked, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerCorked, value);
}
///
/// The mediaplayer is uncorked
///
public event EventHandler Uncorked
{
add => EventManager.AttachEvent(EventType.MediaPlayerUncorked, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerUncorked, value);
}
///
/// The mediaplayer is muted
///
public event EventHandler Muted
{
add => EventManager.AttachEvent(EventType.MediaPlayerMuted, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerMuted, value);
}
///
/// The mediaplayer is unmuted
///
public event EventHandler Unmuted
{
add => EventManager.AttachEvent(EventType.MediaPlayerUnmuted, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerUnmuted, value);
}
///
/// The mediaplayer's volume changed
///
public event EventHandler VolumeChanged
{
add => EventManager.AttachEvent(EventType.MediaPlayerAudioVolume, value);
remove => EventManager.DetachEvent(EventType.MediaPlayerAudioVolume, value);
}
#endregion
///
/// Dispose override
/// Effectively stops playback and disposes a media if any
///
/// release any unmanaged resources
protected override void Dispose(bool disposing)
{
if (IsDisposed || NativeReference == IntPtr.Zero)
return;
if(disposing)
{
if(IsPlaying)
Stop();
if (_gcHandle.IsAllocated)
_gcHandle.Free();
}
base.Dispose(disposing);
}
}
/// Description for titles
public enum Title
{
///
/// Menu title
///
Menu = 1,
///
/// Interactive title
///
Interactive = 2
}
/// Marq options definition
public enum VideoMarqueeOption
{
///
/// Enable marquee
///
Enable = 0,
///
/// Text marquee
///
Text = 1,
///
/// Color marquee
///
Color = 2,
///
/// Opacity marquee
///
Opacity = 3,
///
/// Position marquee
///
Position = 4,
///
/// Refresh marquee
///
Refresh = 5,
///
/// Size marquee
///
Size = 6,
///
/// Timeout marquee
///
Timeout = 7,
///
/// X marquee
///
X = 8,
///
/// Y marquee
///
Y = 9
}
/// Navigation mode
public enum NavigationMode
{
///
/// Activate
///
Activate = 0,
///
/// Navigation up
///
Up = 1,
///
/// Navigation down
///
Down = 2,
///
/// Navigation left
///
Left = 3,
///
/// Navigation right
///
Right = 4,
///
/// Navigation popup
///
Popup = 5
}
/// Enumeration of values used to set position (e.g. of video title).
public enum Position
{
///
/// Disable
///
Disable = -1,
///
/// Center video title
///
Center = 0,
///
/// Left video title
///
Left = 1,
///
/// Right video title
///
Right = 2,
///
/// Top video title
///
Top = 3,
///
/// TopLeft video title
///
TopLeft = 4,
///
/// TopRight video title
///
TopRight = 5,
///
/// Bottom video title
///
Bottom = 6,
///
/// BottomLeft video title
///
BottomLeft = 7,
///
/// BottomRight video title
///
BottomRight = 8
}
///
/// Enumeration of teletext keys than can be passed via
/// libvlc_video_set_teletext()
///
public enum TeletextKey
{
///
/// Red
///
Red = 7471104,
///
/// Green
///
Green = 6750208,
///
/// Yellow
///
Yellow = 7929856,
///
/// Blue
///
Blue = 6422528,
///
/// Index
///
Index = 6881280
}
///
/// option values for libvlc_video_{get,set}_logo_{int,string}
///
public enum VideoLogoOption
{
///
/// Enable
///
Enable = 0,
///
/// string argument, "file,d,t;file,d,t;..."
///
File = 1,
///
/// X
///
X = 2,
///
/// Y
///
Y = 3,
///
/// Delay
///
Delay = 4,
///
/// Repeat
///
Repeat = 5,
///
/// Opacity
///
Opacity = 6,
///
/// Position
///
Position = 7
}
///
/// option values for libvlc_video_{get,set}_adjust_{int,float,bool}
///
public enum VideoAdjustOption
{
///
/// Enable
///
Enable = 0,
///
/// Contrast
///
Contrast = 1,
///
/// Brightness
///
Brightness = 2,
///
/// Hue
///
Hue = 3,
///
/// Saturation
///
Saturation = 4,
///
/// Gamma
///
Gamma = 5
}
///
/// Audio channels
///
public enum AudioOutputChannel
{
///
/// Error
///
Error = -1,
///
/// Stereo mode
///
Stereo = 1,
///
/// RStereo mode
///
RStereo = 2,
///
/// Left mode
///
Left = 3,
///
/// Right mode
///
Right = 4,
///
/// Dolbys mode
///
Dolbys = 5
}
/// Media player roles.
///
/// LibVLC 3.0.0 and later.
/// See
///
public enum MediaPlayerRole
{
/// Don't use a media player role
None = 0,
/// Music (or radio) playback
Music = 1,
/// Video playback
Video = 2,
/// Speech, real-time communication
Communication = 3,
/// Video game
Game = 4,
/// User interaction feedback
LiblvcRoleNotification = 5,
/// Embedded animation (e.g. in web page)
Animation = 6,
/// Audio editing/production
Production = 7,
/// Accessibility
Accessibility = 8,
/// Testing
Test = 9
}
}