Popular Post MattyD Posted April 12 Popular Post Posted April 12 (edited) This is a spin off the thread from here. I've moved this out of the collab space so I don't feel guilty about making sweeping changes when the mood hits me. But I'm still more than happy for this to be a community project at heart. Just a quick comment about the code: for this API, it looks like we need to construct some objects internally, which is a bit of a learning curve - but hopefully this example will provide a bit of background as to whats happening there... Original Attempt: Spoiler expandcollapse popup#AutoIt3Wrapper_UseX64=N ;test both x86/x64 #include <APIErrorsConstants.au3> #include <StructureConstants.au3> #include <GUIConstants.au3> #include <Array.au3> #include <winapi.au3> Opt("MustDeclareVars", True) Local $sTestFile = @ScriptDir & "\relax.mp4" #Region Constants ;~ Global Const $S_OK = 0 ;already decalred via winapi.au3 Global Const $S_FALSE = 1 ;~ Global Const $E_NOINTERFACE = 0x80004002 ;already decalred via winapi.au3 Global Const $MF_VERSION = 0x00020070 ; 0x00010070 is needed for pre-Win7. Global Enum $MFSTARTUP_FULL, $MFSTARTUP_LITE, $MFSTARTUP_NOSOCKET = $MFSTARTUP_LITE Global Const $sCLSID_MFMediaEngineClassFactory = "{B44392DA-499B-446b-A4CB-005FEAD0E6D5}" ;VARTYPE Global Enum $VT_EMPTY = 0, _ $VT_NULL = 1, _ $VT_I2 = 2, _ $VT_I4 = 3, _ $VT_R4 = 4, _ $VT_R8 = 5, _ $VT_CY = 6, _ $VT_DATE = 7, _ $VT_BSTR = 8, _ $VT_DISPATCH = 9, _ $VT_ERROR = 10, _ $VT_BOOL = 11, _ $VT_VARIANT = 12, _ $VT_UNKNOWN = 13, _ $VT_DECIMAL = 14, _ $VT_I1 = 16, _ $VT_UI1 = 17, _ $VT_UI2 = 18, _ $VT_UI4 = 19, _ $VT_I8 = 20, _ $VT_UI8 = 21, _ $VT_INT = 22, _ $VT_UINT = 23, _ $VT_VOID = 24, _ $VT_HRESULT = 25, _ $VT_PTR = 26, _ $VT_SAFEARRAY = 27, _ $VT_CARRAY = 28, _ $VT_USERDEFINED = 29, _ $VT_LPSTR = 30, _ $VT_LPWSTR = 31, _ $VT_RECORD = 36, _ $VT_INT_PTR = 37, _ $VT_UINT_PTR = 38, _ $VT_FILETIME = 64, _ $VT_BLOB = 65, _ $VT_STREAM = 66, _ $VT_STORAGE = 67, _ $VT_STREAMED_OBJECT = 68, _ $VT_STORED_OBJECT = 69, _ $VT_BLOB_OBJECT = 70, _ $VT_CF = 71, _ $VT_CLSID = 72, _ $VT_VERSIONED_STREAM = 73, _ $VT_BSTR_BLOB = 0xfff, _ $VT_VECTOR = 0x1000, _ $VT_ARRAY = 0x2000, _ $VT_BYREF = 0x4000, _ $VT_RESERVED = 0x8000, _ $VT_ILLEGAL = 0xffff, _ $VT_ILLEGALMASKED = 0xfff, _ $VT_TYPEMASK = 0xfff ; _MF_ATTRIBUTE_TYPE Global Enum $MF_ATTRIBUTE_UINT32 = $VT_UI4, _ $MF_ATTRIBUTE_UINT64 = $VT_UI8, _ $MF_ATTRIBUTE_DOUBLE = $VT_R8, _ $MF_ATTRIBUTE_GUID = $VT_CLSID, _ $MF_ATTRIBUTE_STRING = $VT_LPWSTR, _ $MF_ATTRIBUTE_BLOB = BitOR($VT_VECTOR, $VT_UI1), _ $MF_ATTRIBUTE_IUNKNOWN = $VT_UNKNOWN ; MF_MEDIA_ENGINE_NETWORK Global Enum $MF_MEDIA_ENGINE_NETWORK_EMPTY, _ $MF_MEDIA_ENGINE_NETWORK_IDLE, _ $MF_MEDIA_ENGINE_NETWORK_LOADING, _ $MF_MEDIA_ENGINE_NETWORK_NO_SOURCE ; MF_MEDIA_ENGINE_ERR Global Enum $MF_MEDIA_ENGINE_ERR_NOERROR, _ $MF_MEDIA_ENGINE_ERR_ABORTED, _ $MF_MEDIA_ENGINE_ERR_NETWORK, _ $MF_MEDIA_ENGINE_ERR_DECODE, _ $MF_MEDIA_ENGINE_ERR_SRC_NOT_SUPPORTED, _ $MF_MEDIA_ENGINE_ERR_ENCRYPTED ; MF_MEDIA_ENGINE_PRELOAD Global Enum $MF_MEDIA_ENGINE_PRELOAD_MISSING, _ $MF_MEDIA_ENGINE_PRELOAD_EMPTY, _ $MF_MEDIA_ENGINE_PRELOAD_NONE, _ $MF_MEDIA_ENGINE_PRELOAD_METADATA, _ $MF_MEDIA_ENGINE_PRELOAD_AUTOMATIC ; MF_MEDIA_ENGINE_CANPLAY Global Enum $MF_MEDIA_ENGINE_CANPLAY_NOT_SUPPORTED, _ $MF_MEDIA_ENGINE_CANPLAY_MAYBE, _ $MF_MEDIA_ENGINE_CANPLAY_PROBABLY ; MF_MEDIA_ENGINE_CREATEFLAGS Global Enum $MF_MEDIA_ENGINE_AUDIOONLY = 0x1, _ $MF_MEDIA_ENGINE_WAITFORSTABLE_STATE = 0x2, _ $MF_MEDIA_ENGINE_FORCEMUTE = 0x4, _ $MF_MEDIA_ENGINE_REAL_TIME_MODE = 0x8, _ $MF_MEDIA_ENGINE_DISABLE_LOCAL_PLUGINS = 0x10, _ $MF_MEDIA_ENGINE_CREATEFLAGS_MASK = 0x1f ; MF_MEDIA_ENGINE_EVENT Global Enum $MF_MEDIA_ENGINE_EVENT_LOADSTART = 1, _ $MF_MEDIA_ENGINE_EVENT_PROGRESS = 2, _ $MF_MEDIA_ENGINE_EVENT_SUSPEND = 3, _ $MF_MEDIA_ENGINE_EVENT_ABORT = 4, _ $MF_MEDIA_ENGINE_EVENT_ERROR = 5, _ $MF_MEDIA_ENGINE_EVENT_EMPTIED = 6, _ $MF_MEDIA_ENGINE_EVENT_STALLED = 7, _ $MF_MEDIA_ENGINE_EVENT_PLAY = 8, _ $MF_MEDIA_ENGINE_EVENT_PAUSE = 9, _ $MF_MEDIA_ENGINE_EVENT_LOADEDMETADATA = 10, _ $MF_MEDIA_ENGINE_EVENT_LOADEDDATA = 11, _ $MF_MEDIA_ENGINE_EVENT_WAITING = 12, _ $MF_MEDIA_ENGINE_EVENT_PLAYING = 13, _ $MF_MEDIA_ENGINE_EVENT_CANPLAY = 14, _ $MF_MEDIA_ENGINE_EVENT_CANPLAYTHROUGH = 15, _ $MF_MEDIA_ENGINE_EVENT_SEEKING = 16, _ $MF_MEDIA_ENGINE_EVENT_SEEKED = 17, _ $MF_MEDIA_ENGINE_EVENT_TIMEUPDATE = 18, _ $MF_MEDIA_ENGINE_EVENT_ENDED = 19, _ $MF_MEDIA_ENGINE_EVENT_RATECHANGE = 20, _ $MF_MEDIA_ENGINE_EVENT_DURATIONCHANGE = 21, _ $MF_MEDIA_ENGINE_EVENT_VOLUMECHANGE = 22, _ $MF_MEDIA_ENGINE_EVENT_FORMATCHANGE = 1000, _ $MF_MEDIA_ENGINE_EVENT_PURGEQUEUEDEVENTS = 1001, _ $MF_MEDIA_ENGINE_EVENT_TIMELINE_MARKER = 1002, _ $MF_MEDIA_ENGINE_EVENT_BALANCECHANGE = 1003, _ $MF_MEDIA_ENGINE_EVENT_DOWNLOADCOMPLETE = 1004, _ $MF_MEDIA_ENGINE_EVENT_BUFFERINGSTARTED = 1005, _ $MF_MEDIA_ENGINE_EVENT_BUFFERINGENDED = 1006, _ $MF_MEDIA_ENGINE_EVENT_FRAMESTEPCOMPLETED = 1007, _ $MF_MEDIA_ENGINE_EVENT_NOTIFYSTABLESTATE = 1008, _ $MF_MEDIA_ENGINE_EVENT_FIRSTFRAMEREADY = 1009, _ $MF_MEDIA_ENGINE_EVENT_TRACKSCHANGE = 1010, _ $MF_MEDIA_ENGINE_EVENT_OPMINFO = 1011, _ $MF_MEDIA_ENGINE_EVENT_RESOURCELOST = 1012, _ $MF_MEDIA_ENGINE_EVENT_DELAYLOADEVENT_CHANGED = 1013, _ $MF_MEDIA_ENGINE_EVENT_STREAMRENDERINGERROR = 1014, _ $MF_MEDIA_ENGINE_EVENT_SUPPORTEDRATES_CHANGED = 1015, _ $MF_MEDIA_ENGINE_EVENT_AUDIOENDPOINTCHANGE = 1016 ; MF_MEDIA_ENGINE_READY Global Enum $MF_MEDIA_ENGINE_READY_HAVE_NOTHING, _ $MF_MEDIA_ENGINE_READY_HAVE_METADATA, _ $MF_MEDIA_ENGINE_READY_HAVE_CURRENT_DATA, _ $MF_MEDIA_ENGINE_READY_HAVE_FUTURE_DATA, _ $MF_MEDIA_ENGINE_READY_HAVE_ENOUGH_DATA ; MF_MEDIA_ENGINE_STATISTIC Global Enum $MF_MEDIA_ENGINE_STATISTIC_FRAMES_RENDERED, _ $MF_MEDIA_ENGINE_STATISTIC_FRAMES_DROPPED, _ $MF_MEDIA_ENGINE_STATISTIC_BYTES_DOWNLOADED, _ $MF_MEDIA_ENGINE_STATISTIC_BUFFER_PROGRESS, _ $MF_MEDIA_ENGINE_STATISTIC_FRAMES_PER_SECOND, _ $MF_MEDIA_ENGINE_STATISTIC_PLAYBACK_JITTER, _ $MF_MEDIA_ENGINE_STATISTIC_FRAMES_CORRUPTED, _ $MF_MEDIA_ENGINE_STATISTIC_TOTAL_FRAME_DELAY ; MF_MEDIA_ENGINE_S3D_PACKING_MODE Global Enum $MF_MEDIA_ENGINE_S3D_PACKING_MODE_NONE, _ $MF_MEDIA_ENGINE_S3D_PACKING_MODE_SIDE_BY_SIDE, _ $MF_MEDIA_ENGINE_S3D_PACKING_MODE_TOP_BOTTOM ; MF_MEDIA_ENGINE_SEEK_MODE Global Enum $MF_MEDIA_ENGINE_SEEK_MODE_NORMAL, _ $MF_MEDIA_ENGINE_SEEK_MODE_APPROXIMATE #EndRegion #Region Interfaces Global Const $sIID_IUnknown = "{00000000-0000-0000-C000-000000000046}" Global Const $sIID_IMFMediaError = "{fc0e10d2-ab2a-4501-a951-06bb1075184c}" Global Const $sIID_IMFMediaEngineSrcElements = "{7a5e5354-b114-4c72-b991-3131d75032ea}" Global Const $sIID_IMFMediaTimeRange = "{db71a2fc-078a-414e-9df9-8c2531b0aa6c}" Global Const $sIID_IMFMediaEngine = "{98a1b0bb-03eb-4935-ae7c-93c1fa0e1c93}" Global Const $sIID_IMFMediaEngineEx = "{83015ead-b1e6-40d0-a98a-37145ffe1ad1}" Global Const $sIID_IMFMediaEngineClassFactory = "{4d645ace-26aa-4688-9be1-df3516990b93}" Global Const $sIID_IMFMediaEngineNotify = "{fee7c112-e776-42b5-9bbf-0048524e2bd5}" Global Const $sIID_IMFMediaEngineAudioEndpointId = "{7a3bac98-0e76-49fb-8c20-8a86fd98eaf2}" Global Const $sIID_IMFMediaEngineExtension = "{2f69d622-20b5-41e9-afdf-89ced1dda04e}" Global Const $IID_IUnknown = _WinAPI_GUIDFromString($sIID_IUnknown) Global Const $IID_IMFMediaEngineNotify = _WinAPI_GUIDFromString($sIID_IMFMediaEngineNotify) Global Const $IID_IMFMediaEngineSrcElements = _WinAPI_GUIDFromString($sIID_IMFMediaEngineSrcElements) Global Const $sIID_IMFAttributes = "{2cd2d921-c447-44a7-a13c-4adabfc247e3}" Global Const $tag_IMFAttributes = _ "GetItem hresult(struct*; struct*);" & _ "GetItemType hresult(struct*; long*);" & _ "CompareItem hresult(struct*; struct*; bool*);" & _ "Compare hresult(ptr; long; bool*);" & _ "GetUINT32 hresult(struct*; uint*);" & _ "GetUINT64 hresult(struct*; uint64*);" & _ "GetDouble hresult(struct*; double*);" & _ "GetGUID hresult(struct*; struct*);" & _ "GetStringLength hresult(struct*; uint*);" & _ "GetString hresult(struct*; wstr; uint; uint*);" & _ "GetAllocatedString hresult(struct*; wstr*; uint*);" & _ "GetBlobSize hresult(struct*; uint*);" & _ "GetBlob hresult(struct*; struct*; uint; uint*);" & _ "GetAllocatedBlob hresult(struct*; ptr*; uint*);" & _ "GetUnknown hresult(struct*; struct*; ptr*);" & _ "SetItem hresult(struct*; struct*);" & _ "DeleteItem hresult(struct*);" & _ "DeleteAllItems hresult();" & _ "SetUINT32 hresult(struct*; uint);" & _ "SetUINT64 hresult(struct*; uint64);" & _ "SetDouble hresult(struct*; double);" & _ "SetGUID hresult(struct*; struct*);" & _ "SetString hresult(struct*; wstr);" & _ "SetBlob hresult(struct*; struct*; uint);" & _ "SetUnknown hresult(struct*; ptr);" & _ "LockStore hresult();" & _ "UnlockStore hresult();" & _ "GetCount hresult(uint*);" & _ "GetItemByIndex hresult(uint; struct*; struct*);" & _ "CopyAllItems hresult(ptr);" Global Const $sIID_IMFMediaEvent = "{DF598932-F10C-4E39-BBA2-C308F101DAA3}" Global Const $tag_IMFMediaEvent = $tag_IMFAttributes & _ "GetType hresult(uint*);" & _ "GetExtendedType hresult(struct*);" & _ "GetStatus hresult([*mut HRESULT]);" & _ "GetValue hresult(struct*);" Global Const $sIID_IMFMediaEventGenerator = "(2cd0bd52-bcd5-4b89-b62c-eadc0c031e7d)" Global Const $tag_IMFMediaEventGenerator = _ "GetEvent hresult(long; ptr*);" & _ "BeginGetEvent hresult(ptr; ptr);" & _ "EndGetEvent hresult(ptr; ptr*);" & _ "QueueEvent hresult(uint; struct*; hresult; struct*);" Global Const $sIID_IMFMediaSource = "{279a808d-aec7-40c8-9c6b-a6b492c78a66}" Global Const $tag_IMFMediaSource = $tag_IMFMediaEventGenerator & _ "GetCharacteristics hresult(uint*);" & _ "CreatePresentationDescriptor hresult(ptr*);" & _ "Start hresult(ptr; struct*; struct*);" & _ "Stop hresult();" & _ "Pause hresult();" & _ "Shutdown hresult();" Global Const $sIID_IMFSourceResolver = "{FBE5A32D-A497-4b61-BB85-97B1A848A6E3}" Global Const $tag_IMFSourceResolver = _ "CreateObjectFromURL hresult(wstr; uint; ptr; long*; ptr*);" & _ "CreateObjectFromByteStream hresult(ptr; wstr; uint; ptr; long*; ptr*);" & _ "BeginCreateObjectFromURL hresult(wstr; uint; ptr; ptr*; ptr; ptr);" & _ "EndCreateObjectFromURL hresult(ptr; long*; ptr*);" & _ "BeginCreateObjectFromByteStream hresult(ptr; wstr; uint; ptr; ptr*; ptr; ptr);" & _ "EndCreateObjectFromByteStream hresult(ptr; long*; ptr*);" & _ "CancelObjectCreation hresult(ptr);" Global Const $tag_IMFMediaEngine = _ "GetError hresult(ptr*);" & _ "SetErrorCode hresult(long);" & _ "SetSourceElements hresult(ptr);" & _ "SetSource hresult(ptr);" & _ "GetCurrentSource hresult(ptr*);" & _ "GetNetworkState short();" & _ "GetPreload long();" & _ "SetPreload hresult(long);" & _ "GetBuffered hresult(ptr*);" & _ "Load hresult();" & _ "CanPlayType hresult(ptr; long*);" & _ "GetReadyState short();" & _ "IsSeeking bool();" & _ "GetCurrentTime double();" & _ "SetCurrentTime hresult(double);" & _ "GetStartTime double();" & _ "GetDuration double();" & _ "IsPaused bool();" & _ "GetDefaultPlaybackRate double();" & _ "SetDefaultPlaybackRate hresult(double);" & _ "GetPlaybackRate double();" & _ "SetPlaybackRate hresult(double);" & _ "GetPlayed hresult(ptr*);" & _ "GetSeekable hresult(ptr*);" & _ "IsEnded bool();" & _ "GetAutoPlay bool();" & _ "SetAutoPlay hresult(bool);" & _ "GetLoop bool();" & _ "SetLoop hresult(bool);" & _ "Play hresult();" & _ "Pause hresult();" & _ "GetMuted bool();" & _ "SetMuted hresult(bool);" & _ "GetVolume double();" & _ "SetVolume hresult(double);" & _ "HasVideo bool();" & _ "HasAudio bool();" & _ "GetNativeVideoSize hresult(uint*; uint*);" & _ "GetVideoAspectRatio hresult(uint*; uint*);" & _ "Shutdown hresult();" & _ "TransferVideoFrame hresult(ptr; struct*; struct*; ulong*);" & _ "OnVideoStreamTick hresult(int64*);" Global Const $tag_IMFMediaEngineAudioEndpointId = _ "SetAudioEndpointId hresult(wstr);" & _ "GetAudioEndpointId hresult(wstr*);" Global Const $tag_IMFMediaEngineClassFactory = _ "CreateInstance hresult(uint; ptr; ptr*);" & _ "CreateTimeRange hresult(ptr*);" & _ "CreateError hresult(ptr*);" Global Const $tag_IMFMediaEngineClassFactory2 = _ "CreateMediaKeys2 hresult(ptr; ptr; ptr; ptr*);" Global Const $tag_IMFMediaEngineClassFactory3 = _ "CreateMediaKeySystemAccess hresult(ptr; ptr*; uint; ptr*);" Global Const $tag_IMFMediaEngineClassFactory4 = _ "CreateContentDecryptionModuleFactory hresult(wstr; struct*; ptr*);" Global Const $tag_IMFMediaEngineClassFactoryEx = _ $tag_IMFMediaEngineClassFactory & _ "CreateMediaSourceExtension hresult(uint; ptr; ptr*);" & _ "CreateMediaKeys hresult(ptr; ptr; ptr*);" & _ "IsTypeSupported hresult(ptr; ptr; bool*);" Global Const $tag_IMFMediaEngineEMENotify = _ "Encrypted none(struct*; uint; ptr);" & _ "WaitingForKey none();" Global Const $tag_IMFMediaEngineEME = _ "Keys hresult(ptr*);" & _ "SetMediaKeys hresult(ptr);" Global Const $tag_IMFMediaEngineEx = _ $tag_IMFMediaEngine & _ "SetSourceFromByteStream hresult(ptr; ptr);" & _ "GetStatistics hresult(long; struct*);" & _ "UpdateVideoStream hresult(struct*; struct*; ulong*);" & _ "GetBalance double();" & _ "SetBalance hresult(double);" & _ "IsPlaybackRateSupported bool(double);" & _ "FrameStep hresult(bool);" & _ "GetResourceCharacteristics hresult(uint*);" & _ "GetPresentationAttribute hresult(struct*; struct*);" & _ "GetNumberOfStreams hresult(uint*);" & _ "GetStreamAttribute hresult(uint; struct*; struct*);" & _ "GetStreamSelection hresult(uint; bool*);" & _ "SetStreamSelection hresult(uint; bool);" & _ "ApplyStreamSelections hresult();" & _ "IsProtected hresult(bool*);" & _ "InsertVideoEffect hresult(ptr; bool);" & _ "InsertAudioEffect hresult(ptr; bool);" & _ "RemoveAllEffects hresult();" & _ "SetTimelineMarkerTimer hresult(double);" & _ "GetTimelineMarkerTimer hresult(double*);" & _ "CancelTimelineMarkerTimer hresult();" & _ "IsStereo3D bool();" & _ "GetStereo3DFramePackingMode hresult(long*);" & _ "SetStereo3DFramePackingMode hresult(long);" & _ "GetStereo3DRenderMode hresult(long*);" & _ "SetStereo3DRenderMode hresult(long);" & _ "EnableWindowlessSwapchainMode hresult(bool);" & _ "GetVideoSwapchainHandle hresult(handle*);" & _ "EnableHorizontalMirrorMode hresult(bool);" & _ "GetAudioStreamCategory hresult(uint*);" & _ "SetAudioStreamCategory hresult(uint);" & _ "GetAudioEndpointRole hresult(uint*);" & _ "SetAudioEndpointRole hresult(uint);" & _ "GetRealTimeMode hresult(bool*);" & _ "SetRealTimeMode hresult(bool);" & _ "SetCurrentTimeEx hresult(double; long);" & _ "EnableTimeUpdateTimer hresult(bool);" Global Const $tag_IMFMediaEngineExtension = _ "CanPlayType hresult(bool; ptr; long*);" & _ "BeginCreateObject hresult(ptr; ptr; long; ptr*; ptr; ptr);" & _ "CancelObjectCreation hresult(ptr);" & _ "EndCreateObject hresult(ptr; ptr*);" Global Const $tag_IMFMediaEngineNeedKeyNotify = _ "NeedKey none(struct*; uint);" Global Const $tag_IMFMediaEngineNotify = _ "EventNotify hresult(uint; ulong_ptr; uint);" Global Const $tag_IMFMediaEngineOPMInfo = _ "GetOPMInfo hresult(long*; bool*);" Global Const $tag_IMFMediaEngineProtectedContent = _ "ShareResources hresult(ptr);" & _ "GetRequiredProtections hresult(uint*);" & _ "SetOPMWindow hresult(hwnd);" & _ "TransferVideoFrame hresult(ptr; struct*; struct*; ulong*; uint*);" & _ "SetContentProtectionManager hresult(ptr);" & _ "SetApplicationCertificate hresult(struct*; uint);" Global Const $tag_IMFMediaEngineSrcElements = _ "GetLength uint();" & _ "GetURL hresult(uint; ptr*);" & _ "GetType hresult(uint; ptr*);" & _ "GetMedia hresult(uint; ptr*);" & _ "AddElement hresult(ptr; ptr; ptr);" & _ "RemoveAllElements hresult();" Global Const $tag_IMFMediaEngineSrcElementsEx = _ $tag_IMFMediaEngineSrcElements & _ "AddElementEx hresult(ptr; ptr; ptr; ptr);" & _ "GetKeySystem hresult(uint; ptr*);" Global Const $tag_IMFMediaEngineSupportsSourceTransfer = _ "ShouldTransferSource hresult(bool*);" & _ "DetachMediaSource hresult(ptr*; ptr*; ptr*);" & _ "AttachMediaSource hresult(ptr; ptr; ptr);" Global Const $tag_IMFMediaEngineTransferSource = _ "TransferSourceToMediaEngine hresult(ptr);" Global Const $tag_IMFMediaEngineWebSupport = _ "ShouldDelayTheLoadEvent bool();" & _ "ConnectWebAudio hresult(uint; ptr*);" & _ "DisconnectWebAudio hresult();" Global Const $tag_IMFMediaError = _ "GetErrorCode short();" & _ "GetExtendedErrorCode hresult();" & _ "SetErrorCode hresult(long);" & _ "SetExtendedErrorCode hresult(hresult);" #EndRegion #Region Properties etc Global Const $MF_MEDIA_ENGINE_AUDIO_CATEGORY = __COM_CreateGUID("{c8d4c51d-350e-41f2-ba46-faebbb0857f6}") Global Const $MF_MEDIA_ENGINE_AUDIO_ENDPOINT_ROLE = __COM_CreateGUID("{d2cb93d1-116a-44f2-9385-f7d0fda2fb46}") Global Const $MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE = __COM_CreateGUID("{4e0212e2-e18f-41e1-95e5-c0e7e9235bc3}") Global Const $MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE9 = __COM_CreateGUID("{052c2d39-40c0-4188-ab86-f828273b7522}") Global Const $MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE10 = __COM_CreateGUID("{11a47afd-6589-4124-b312-6158ec517fc3}") Global Const $MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE11 = __COM_CreateGUID("{1cf1315f-ce3f-4035-9391-16142f775189}") Global Const $MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE_EDGE = __COM_CreateGUID("{a6f3e465-3aca-442c-a3f0-ad6ddad839ae}") Global Const $MF_MEDIA_ENGINE_CALLBACK = __COM_CreateGUID("{c60381b8-83a4-41f8-a3d0-de05076849a9}") Global Const $MF_MEDIA_ENGINE_COMPATIBILITY_MODE = __COM_CreateGUID("{3ef26ad4-dc54-45de-b9af-76c8c66bfa8e}") Global Const $MF_MEDIA_ENGINE_COMPATIBILITY_MODE_WIN10 = __COM_CreateGUID("{5b25e089-6ca7-4139-a2cb-fcaab39552a3}") Global Const $MF_MEDIA_ENGINE_COMPATIBILITY_MODE_WWA_EDGE = __COM_CreateGUID("{15b29098-9f01-4e4d-b65a-c06c6c89da2a}") Global Const $MF_MEDIA_ENGINE_CONTENT_PROTECTION_FLAGS = __COM_CreateGUID("{e0350223-5aaf-4d76-a7c3-06de70894db4}") Global Const $MF_MEDIA_ENGINE_CONTENT_PROTECTION_MANAGER = __COM_CreateGUID("{fdd6dfaa-bd85-4af3-9e0f-a01d539d876a}") Global Const $MF_MEDIA_ENGINE_CONTINUE_ON_CODEC_ERROR = __COM_CreateGUID("{dbcdb7f9-48e4-4295-b70d-d518234eeb38}") Global Const $MF_MEDIA_ENGINE_COREWINDOW = __COM_CreateGUID("{fccae4dc-0b7f-41c2-9f96-4659948acddc}") Global Const $MF_MEDIA_ENGINE_DXGI_MANAGER = __COM_CreateGUID("{065702da-1094-486d-8617-ee7cc4ee4648}") Global Const $MF_MEDIA_ENGINE_EME_CALLBACK = __COM_CreateGUID("{494553a7-a481-4cb7-bec5-380903513731}") Global Const $MF_MEDIA_ENGINE_EXTENSION = __COM_CreateGUID("{3109fd46-060d-4b62-8dcf-faff811318d2}") Global Const $MF_MEDIA_ENGINE_MEDIA_PLAYER_MODE = __COM_CreateGUID("{3ddd8d45-5aa1-4112-82e5-36f6a2197e6e}") Global Const $MF_MEDIA_ENGINE_NEEDKEY_CALLBACK = __COM_CreateGUID("{7ea80843-b6e4-432c-8ea4-7848ffe4220e}") Global Const $MF_MEDIA_ENGINE_OPM_HWND = __COM_CreateGUID("{a0be8ee7-0572-4f2c-a801-2a151bd3e726}") Global Const $MF_MEDIA_ENGINE_PLAYBACK_HWND = __COM_CreateGUID("{d988879b-67c9-4d92-baa7-6eadd446039d}") Global Const $MF_MEDIA_ENGINE_PLAYBACK_VISUAL = __COM_CreateGUID("{6debd26f-6ab9-4d7e-b0ee-c61a73ffad15}") Global Const $MF_MEDIA_ENGINE_SOURCE_RESOLVER_CONFIG_STORE = __COM_CreateGUID("{0ac0c497-b3c4-48c9-9cde-bb8ca2442ca3}") Global Const $MF_MEDIA_ENGINE_STREAM_CONTAINS_ALPHA_CHANNEL = __COM_CreateGUID("{5cbfaf44-d2b2-4cfb-80a7-d429c74c789d}") Global Const $MF_MEDIA_ENGINE_SYNCHRONOUS_CLOSE = __COM_CreateGUID("{c3c2e12f-7e0e-4e43-b91c-dc992ccdfa5e}") Global Const $MF_MEDIA_ENGINE_TELEMETRY_APPLICATION_ID = __COM_CreateGUID("{1e7b273b-a7e4-402a-8f51-c48e88a2cabc}") Global Const $MF_MEDIA_ENGINE_TRACK_ID = __COM_CreateGUID("{65bea312-4043-4815-8eab-44dce2ef8f2a}") Global Const $MF_MEDIA_ENGINE_VIDEO_OUTPUT_FORMAT = __COM_CreateGUID("{5066893c-8cf9-42bc-8b8a-472212e52726}") #EndRegion #Region Internal Objects ;;;;;;;;;;;;;;;;;;;;;;;; IUnknown Methods ;;;;;;;;;;;;;;;;;;;;;; Func IUnknown_QueryInterface($pThis, $pTestIID, $ppObj) ;We only support 1 vTab per Object ATM. Local $hResult = $S_OK Local $tRetObj, $tThis Local $tTestIID = DllStructCreate("byte dIID[16]", $pTestIID) Local $tIIDList, $tSupIID If Not $ppObj Then $hResult = $E_POINTER Else $tRetObj = DllStructCreate("ptr pObj", $ppObj) $tThis = DllStructCreate("ptr pVTab;ptr iRefCnt;ptr pIIDList", $pThis) $tIIDList = DllStructCreate("int iIfaceCnt", $tThis.pIIDList) $tIIDList = DllStructCreate(StringFormat("align 4; int iIfaceCnt;ptr pIID[%d]", $tIIDList.iIfaceCnt), $tThis.pIIDList) For $i = 1 To $tIIDList.iIfaceCnt $tSupIID = DllStructCreate("byte dIID[16]", $tIIDList.pIID(($i))) If $tTestIID.dIID = $tSupIID.dIID Then $tRetObj.pObj = $pThis IUnknown_AddRef($pThis) ExitLoop EndIf Next If $i > $tIIDList.iIfaceCnt Then $tRetObj.pObj = 0 $hResult = $E_NOINTERFACE EndIf EndIf Return $hResult EndFunc Func IUnknown_AddRef($pThis) Local $tThis = DllStructCreate("ptr pVTab;int iRefCnt", $pThis) $tThis.iRefCnt += 1 Return $tThis.iRefCnt EndFunc Func IUnknown_Release($pThis) Local $tThis = DllStructCreate("ptr pVTab;int iRefCnt", $pThis) $tThis.iRefCnt -= 1 Return $tThis.iRefCnt EndFunc Local $tIUnknown_QueryInterface = DllCallbackRegister("IUnknown_QueryInterface", "long", "ptr;ptr;ptr") Local $tIUnknown_AddRef = DllCallbackRegister("IUnknown_AddRef", "long", "ptr") Local $tIUnknown_Release = DllCallbackRegister("IUnknown_Release", "long", "ptr") ;;;;;;;;;;;;;;;;;;;;;;;; IMFMediaEngineNotify ;;;;;;;;;;;;;;;;;;;;;; ; IMFMediaEngineNotify::EventNotify is defined further down... Local $tIMFMediaEngineNotify_EventNotify = DllCallbackRegister("IMFEventNotiy_EventNotify", "long", "ptr;dword;dword_ptr;dword") ;Create the IMFMediaEngineNotify vtable. Local $tIMFMediaEngineNotify_Vtab = DllStructCreate("ptr pFunc[4]") $tIMFMediaEngineNotify_Vtab.pFunc(1) = DllCallbackGetPtr($tIUnknown_QueryInterface) $tIMFMediaEngineNotify_Vtab.pFunc(2) = DllCallbackGetPtr($tIUnknown_AddRef) $tIMFMediaEngineNotify_Vtab.pFunc(3) = DllCallbackGetPtr($tIUnknown_Release) $tIMFMediaEngineNotify_Vtab.pFunc(4) = DllCallbackGetPtr($tIMFMediaEngineNotify_EventNotify) ;Supported IID list for IUnkown::QueryInterface Local $tEventNotify_IIDList = DllStructCreate("align 4;int iCount;ptr pIID[2];") $tEventNotify_IIDList.iCount = 2 $tEventNotify_IIDList.pIID(1) = DllStructGetPtr($IID_IUnknown) $tEventNotify_IIDList.pIID(2) = DllStructGetPtr($IID_IMFMediaEngineNotify) ;Required object layout for our implementation of IUnknown - might need to rethink layout to supporting different interfaces. Local $tIMFMediaEngineNotify = DllStructCreate("ptr pVTab;int iRefCnt;ptr pIIDList;") $tIMFMediaEngineNotify.pVtab = DllStructGetPtr($tIMFMediaEngineNotify_Vtab) $tIMFMediaEngineNotify.pIIDList = DllStructGetPtr($tEventNotify_IIDList) ;Initailise the object. Local $pIMFMediaEngineNotify = DllStructGetPtr($tIMFMediaEngineNotify) IUnknown_AddRef($pIMFMediaEngineNotify) ;;;;;;;;;;;;;;;;;;;;;;;; IMFMediaEngineSrcElements ;;;;;;;;;;;;;;;;;;;;;; ;Might not need this after all!!! ; This is essetially an array of bstr - so might be able to write these funcs. ; if we have to manually code a bunch of objects, this could become unamanageable! ;~ Local $tIMFMediaEngineSrcElements_GetLength = DllCallbackRegister("IMFMediaEngineSrcElements_GetLength", "uint", "ptr") ;~ Local $tIMFMediaEngineSrcElements_GetUrl = DllCallbackRegister("IMFMediaEngineSrcElements_GetUrl", "long", "ptr; uint; ptr") ;~ Local $tIMFMediaEngineSrcElements_GetType = DllCallbackRegister("IMFMediaEngineSrcElements_GetType", "long", "ptr; uint; ptr") ;~ Local $tIMFMediaEngineSrcElements_GetMedia = DllCallbackRegister("IMFMediaEngineSrcElements_GetMedia", "long", "ptr; uint; ptr") ;~ Local $tIMFMediaEngineSrcElements_AddElement = DllCallbackRegister("IMFMediaEngineSrcElements_AddElement", "long", "ptr; ptr; ptr; ptr") ;~ Local $tIMFMediaEngineSrcElements_RemoveAllElements = DllCallbackRegister("IMFMediaEngineSrcElements_RemoveAllElements", "long", "ptr") Local $tIMFMediaEngineSrcElements_Vtab = DllStructCreate("ptr pFunc[9]") $tIMFMediaEngineSrcElements_Vtab(1) = DllCallbackGetPtr($tIUnknown_QueryInterface) $tIMFMediaEngineSrcElements_Vtab(2) = DllCallbackGetPtr($tIUnknown_AddRef) $tIMFMediaEngineSrcElements_Vtab(3) = DllCallbackGetPtr($tIUnknown_Release) ;~ $tIMFMediaEngineSrcElements_Vtab(4) = DllCallbackGetPtr($tIMFMediaEngineSrcElements_GetLength) ;~ $tIMFMediaEngineSrcElements_Vtab(5) = DllCallbackGetPtr($tIMFMediaEngineSrcElements_GetUrl) ;~ $tIMFMediaEngineSrcElements_Vtab(6) = DllCallbackGetPtr($tIMFMediaEngineSrcElements_GetType) ;~ $tIMFMediaEngineSrcElements_Vtab(7) = DllCallbackGetPtr($tIMFMediaEngineSrcElements_GetMedia) ;~ $tIMFMediaEngineSrcElements_Vtab(8) = DllCallbackGetPtr($tIMFMediaEngineSrcElements_AddElement) ;~ $tIMFMediaEngineSrcElements_Vtab(9) = DllCallbackGetPtr($tIMFMediaEngineSrcElements_RemoveAllElements) Local $tIMFMediaEngineSrcElements_IIDList = DllStructCreate("align 4;int iCount;ptr pIID[2];") $tIMFMediaEngineSrcElements_IIDList.iCount = 2 $tIMFMediaEngineSrcElements_IIDList.pIID(1) = DllStructGetPtr($IID_IUnknown) $tIMFMediaEngineSrcElements_IIDList.pIID(2) = DllStructGetPtr($IID_IMFMediaEngineSrcElements) Local $tIMFMediaEngineSrcElements = DllStructCreate("ptr pVTab;int iRefCnt;ptr pIIDList;int iSrcElCnt;ptr pSrcElList") $tIMFMediaEngineSrcElements.pVtab = DllStructGetPtr($tIMFMediaEngineSrcElements_Vtab) $tIMFMediaEngineSrcElements.pIIDList = DllStructGetPtr($tIMFMediaEngineSrcElements_IIDList) ;Initailise the object. Local $pIMFMediaEngineSrcElements = DllStructGetPtr($tIMFMediaEngineSrcElements) IUnknown_AddRef($pIMFMediaEngineSrcElements) #EndRegion Local $hWnd = GUICreate("Media Engine", 800, 600, -1, -1, $WS_OVERLAPPEDWINDOW) _MF_Startup() ;Create the callback obj Local $oIMFMediaEngineNotify = ObjCreateInterface($pIMFMediaEngineNotify, $sIID_IMFMediaEngineNotify, $tag_IMFMediaEngineNotify) ConsoleWrite(StringFormat("(%d,0) IsObj($oIMFMediaEngineNotify) = %s", @ScriptLineNumber, IsObj($oIMFMediaEngineNotify)) & @CRLF & @CRLF) ;Test our object!! ;~ ConsoleWrite("QueryInterface Test:" & @CRLF) ;~ Local $pIUnknown, $tGUID = _WinAPI_GUIDFromString($sIID_IUnknown) ;~ $oIMFMediaEngineNotify.QueryInterface(DllStructGetPtr($tGUID), $pIUnknown) ;~ ConsoleWrite(StringFormat("$pIUnknown = %s", Ptr($pIUnknown)) & @CRLF) ;~ Local $oIUnknown = ObjCreateInterface($pIUnknown, $sIID_IUnknown, "") ;~ ConsoleWrite("RefCnt = " & $oIUnknown.Release() & ", .Release()" & @CRLF & @CRLF) ;Create Media Engine Factory - Local $oIMFEngineClassFact = ObjCreateInterface($sCLSID_MFMediaEngineClassFactory, $sIID_IMFMediaEngineClassFactory, $tag_IMFMediaEngineClassFactory) ;Create attrib store for - basically config for factory Local $pAttributes = _MF_CreateAttributes(1) Local $oAttributes = ObjCreateInterface($pAttributes, $sIID_IMFAttributes, $tag_IMFAttributes) ;https://learn.microsoft.com/en-us/windows/win32/api/mfmediaengine/nf-mfmediaengine-imfmediaengineclassfactory-createinstance ;Set the callback func. Required!! Local $tVtIUnknown = DllStructCreate("align 2;ushort vt;word Pad[3];ptr IUnknown;") $tVtIUnknown.vt = $MF_ATTRIBUTE_IUNKNOWN $tVtIUnknown.IUnknown = $pIMFMediaEngineNotify $oAttributes.SetItem($MF_MEDIA_ENGINE_CALLBACK, $tVtIUnknown) ; We need to tell the engine to use its renderer by setting a render target! Local $tVtHwnd = DllStructCreate("align 2;ushort vt;word Pad[3];uint64 hwnd;") $tVtHwnd.vt = $MF_ATTRIBUTE_UINT64 $tVtHwnd.hwnd = $hWnd $oAttributes.SetItem($MF_MEDIA_ENGINE_PLAYBACK_HWND, $tVtHwnd) Local $pMFEngine ;$oIMFEngine must be global for the event handler. ;(The ptr for $oIMFEngine not passed to the callback as far as I can see) Global $oIMFEngine ;Create the Engine Local $hResult = $oIMFEngineClassFact.CreateInstance(0, $pAttributes, $pMFEngine) ;MF_E_ATTRIBUTENOTFOUND = C00D36E6 ConsoleWrite(StringFormat("(%d,0) Fact.CreateInstance(), hr = 0x%08x", @ScriptLineNumber, $hResult) & @CRLF) $oIMFEngine = ObjCreateInterface($pMFEngine, $sIID_IMFMediaEngine, $tag_IMFMediaEngine) ConsoleWrite(StringFormat("(%d,0) IMFEngine Created = %s", @ScriptLineNumber, (IsObj($oIMFEngine) = 1)) & @CRLF) ;Next step for sorting out the media source. - Maybe not required after all ;~ Local $tGUID = _WinAPI_GUIDFromString($sIID_IMFMediaEngineSrcElements) ;~ Local $oIMFMediaEngineSrcElements = ObjCreateInterface($pMFEngine, $sIID_IMFMediaEngineSrcElements, $tag_IMFMediaEngineSrcElements) ;~ ConsoleWrite(StringFormat("(%d,0) $oIMFMediaEngineSrcElements Created = %s", @ScriptLineNumber, (IsObj($oIMFMediaEngineSrcElements) = 1)) & @CRLF) ;Testing!!! ConsoleWrite("Test a few notifications...." & @CRLF) $oIMFEngine.SetMuted(True) $oIMFEngine.SetMuted(False) Local $sSource = _WinAPI_SysAllocString($sTestFile) $hResult = $oIMFEngine.SetSource($sSource) ConsoleWrite(StringFormat("(%d,0) %s hresult = 0x%08X", @ScriptLineNumber, "$oIMFEngine.SetSource", $hResult) & @CRLF) $oIMFEngine.Load() ConsoleWrite(StringFormat("(%d,0) %s hresult = 0x%08X", @ScriptLineNumber, "$oIMFEngine.Load", $hResult) & @CRLF) $oIMFEngine.Play() ConsoleWrite(StringFormat("(%d,0) %s hresult = 0x%08X", @ScriptLineNumber, "$oIMFEngine.Play", $hResult) & @CRLF) GUISetState() ;~ ;Test thread pause.. Anti-crash caused via notifications test! -- In uncommenented you will need to kill script with task manager. ;~ Local $aCall = DllCall("kernel32.dll", "dword", "GetCurrentThreadId") ;~ Local $iThreadID = $aCall[0] ;~ $aCall = DllCall("kernel32.dll", "ptr", "OpenThread", "dword", 0x001F03FF, "int", 0, "dword", $iThreadID) ;~ Local $hThread = $aCall[0] ;~ DllCall("kernel32.dll", "dword", "SuspendThread", "ptr", $hThread) While True Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd $oIMFEngine.Shutdown() _MF_Shutdown() #Region Event Handler Func IMFEventNotiy_EventNotify($pThis, $iEvent, $iParam1, $iParam2) ;~ Return Switch $iEvent Case $MF_MEDIA_ENGINE_EVENT_EMPTIED ConsoleWrite(StringFormat("Event: %-4d > %s", $iEvent, "Emptied") & @CRLF) Case $MF_MEDIA_ENGINE_EVENT_PLAY ConsoleWrite(StringFormat("Event: %-4d > %s", $iEvent, "Play") & @CRLF) Case $MF_MEDIA_ENGINE_EVENT_WAITING ConsoleWrite(StringFormat("Event: %-4d > %s", $iEvent, "Waiting") & @CRLF) Case $MF_MEDIA_ENGINE_EVENT_PLAYING ConsoleWrite(StringFormat("Event: %-4d > %s", $iEvent, "Playing") & @CRLF) Case $MF_MEDIA_ENGINE_EVENT_TIMEUPDATE ConsoleWrite(StringFormat("Event: %-4d > %s", $iEvent, "Time Update") & @CRLF) Case $MF_MEDIA_ENGINE_EVENT_CANPLAY ConsoleWrite(StringFormat("Event: %-4d > %s", $iEvent, "CanPlay") & @CRLF) Case $MF_MEDIA_ENGINE_EVENT_VOLUMECHANGE ConsoleWrite(StringFormat("Event: %-4d >, %s, Vol: %f, Muted: %s", $iEvent, "Volume Change", $oIMFEngine.GetVolume(), $oIMFEngine.GetMuted()) & @CRLF) Case $MF_MEDIA_ENGINE_EVENT_PURGEQUEUEDEVENTS ConsoleWrite(StringFormat("Event: %-4d > %s", $iEvent, "Purge Queued Events") & @CRLF) Case Else ConsoleWrite(StringFormat("Event: %-4d > P1: %d, P2 %d", $iEvent, $iParam1, $iParam2) & @CRLF) EndSwitch EndFunc #EndRegion #Region Funcs ; replace with _WinAPI_GUIDFromString() Func __COM_CreateGUID($sGUID = "{00000000-0000-0000-0000-000000000000}", $pAddress = 0) Local $tGUID = ($pAddress And IsPtr($pAddress)) ? DllStructCreate($tagGUID, $pAddress) : DllStructCreate($tagGUID) Local $aGUID = StringSplit(StringRegExpReplace($sGUID, "[{}]", ""), "-", 2) If UBound($aGUID) <> 5 Then Return SetError($ERROR_INVALID_PARAMETER, 0, False) DllStructSetData($tGUID, 1, Dec($aGUID[0])) DllStructSetData($tGUID, 2, Dec($aGUID[1])) DllStructSetData($tGUID, 3, Dec($aGUID[2])) DllStructSetData($tGUID, 4, Binary("0x" & $aGUID[3] & $aGUID[4])) Return $tGUID EndFunc ;==>__COM_CreateGUID Func __COM_ReadGUIDAt($pGUID) Local $tGUID, $sGUID If (Not $pGUID) Or (Not IsPtr($pGUID)) Then Return SetError($ERROR_INVALID_PARAMETER, 0, "") $tGUID = DllStructCreate($tagGUID, $pGUID) $sGUID = StringFormat("{%s-%s-%s-%s-%s}", _ Hex(DllStructGetData($tGUID, 1), 8), _ Hex(DllStructGetData($tGUID, 2), 4), _ Hex(DllStructGetData($tGUID, 3), 4), _ StringMid(DllStructGetData($tGUID, 4), 3, 4), _ StringMid(DllStructGetData($tGUID, 4), 7, 12)) Return $sGUID EndFunc ;==>__COM_ReadGUIDAt Func __COM_CompareGUIDs($tGUID1, $tGUID2) If DllStructGetSize($tGUID1) < 16 Then Return SetError($ERROR_INVALID_PARAMETER, 0, False) If DllStructGetSize($tGUID2) < 16 Then Return SetError($ERROR_INVALID_PARAMETER, 0, False) Local $tBuff1 = DllStructCreate("byte GUID[16]", DllStructGetPtr($tGUID1)) Local $tBuff2 = DllStructCreate("byte GUID[16]", DllStructGetPtr($tGUID2)) ConsoleWrite($tBuff1.GUID & @CRLF) ConsoleWrite($tBuff2.GUID & @CRLF) Return DllStructGetData($tBuff1, 1) = DllStructGetData($tBuff2, 1) EndFunc ;==>__COM_CompareGUIDs ;Wrapped funcs generally populate @error with hresult. ;So this ensures we have sensible errors if DllCall() fails.. Func __COM_GetDllError($iError = @error) Switch $iError Case 0 $iError = $ERROR_SUCCESS Case 1 $iError = $ERROR_DLL_INIT_FAILED Case Else $iError = $ERROR_INVALID_PARAMETER EndSwitch Return $iError EndFunc ;==>__COM_GetDllError Func _MF_CreateMediaSession($pConfig = 0) Local $aCall = DllCall("mf.dll", "long", "MFCreateMediaSession", "ptr", $pConfig, "ptr*", 0) If @error Then Return SetError(__COM_GetDllError(), 0, 0) Return SetError($aCall[0], 0, $aCall[2]) EndFunc ;==>_MF_CreateMediaSession Func _MF_CreateTopology() Local $aCall = DllCall("mf.dll", "long", "MFCreateTopology", "ptr*", 0) If @error Then Return SetError(__COM_GetDllError(), 0, 0) Return SetError($aCall[0], 0, $aCall[1]) EndFunc ;==>_MF_CreateTopology Func _MF_CreateTopologyNode($iNodeType) Local $aCall = DllCall("mf.dll", "long", "MFCreateTopologyNode", "long", $iNodeType, "ptr*", 0) If @error Then Return SetError(__COM_GetDllError(), 0, 0) Return SetError($aCall[0], 0, $aCall[2]) EndFunc ;==>_MF_CreateTopologyNode Func _MF_CreateAudioRendererActivate() Local $aCall = DllCall("mf.dll", "long", "MFCreateAudioRendererActivate", "ptr*", 0) If @error Then Return SetError(__COM_GetDllError(), 0, 0) Return SetError($aCall[0], 0, $aCall[1]) EndFunc ;==>_MF_CreateAudioRendererActivate Func _MF_CreateVideoRendererActivate($hVideo) Local $aCall = DllCall("mf.dll", "long", "MFCreateVideoRendererActivate", "hwnd", $hVideo, "ptr*", 0) If @error Then Return SetError(__COM_GetDllError(), 0, 0) Return SetError($aCall[0], 0, $aCall[2]) EndFunc ;==>_MF_CreateVideoRendererActivate Func _MF_Startup($iFlags = $MFSTARTUP_NOSOCKET) Local $aCall = DllCall("mfplat.dll", "long", "MFStartup", "ulong", $MF_VERSION, "dword", $iFlags) If @error Then Return SetError(__COM_GetDllError(), 0, False) Return SetError($aCall[0], 0, $aCall[0] = $S_OK) EndFunc ;==>_MF_Startup Func _MF_Shutdown() Local $aCall = DllCall("mfplat.dll", "long", "MFShutdown") If @error Then Return SetError(__COM_GetDllError(), 0, False) Return SetError($aCall[0], 0, $aCall[0] = $S_OK) EndFunc ;==>_MF_Shutdown Func _MF_CreateSourceResolver() Local $aCall = DllCall("mfplat.dll", "long", "MFCreateSourceResolver", "ptr*", 0) If @error Then Return SetError(__COM_GetDllError(), 0, False) Return SetError($aCall[0], 0, $aCall[1]) EndFunc ;==>_MF_CreateSourceResolver Func _MF_CreateAttributes($iInitialSize = 0) Local $aCall = DllCall("mfplat.dll", "long", "MFCreateAttributes", "ptr*", 0, "uint", $iInitialSize) If @error Then Return SetError(__COM_GetDllError(), 0, 0) Return SetError($aCall[0], 0, $aCall[1]) EndFunc Func _WinAPI_SysAllocString($sString) Local $aCall = DllCall("OleAut32.dll", "handle", "SysAllocString", "wstr", $sString) If @error Then Return SetError(__COM_GetDllError(), 0, 0) Return $aCall[0] EndFunc ;==>_WinAPI_SysAllocString #EndRegion Funcs Updated example 20/4 - Load media file, progress/seek bar. PlayerDemo 1.1.zip Edited Saturday at 02:47 PM by MattyD KaFu, pat4005, argumentum and 2 others 5
Nine Posted April 13 Posted April 13 Replacing : Func _WinAPI_SysAllocString($sString) Local $aCall = DllCall("mfplat.dll", "handle", "OleAut32.dll", "wchar", $sString) If @error Then Return SetError(__COM_GetDllError(), 0, 0) Return $aCall[0] EndFunc with : Func _WinAPI_SysAllocString($sString) Local $aCall = DllCall("OleAut32.dll", "handle", "SysAllocString", "wstr", $sString) If @error Then Return SetError(__COM_GetDllError(), 0, 0) Return $aCall[0] EndFunc ;==>_WinAPI_SysAllocString And removing the , $oIMFEngine.CanPlay() in event handler proc. Now starts correctly. But after a few events the script crashes. However from time to time, the event handler stops receiving messages and the video runs normally. In this particular case, you cannot stop the script with the close button. You need to interrupt it with task manager. MattyD 1 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Debug Messages Monitor UDF Screen Scraping Round Corner GUI UDF Multi-Threading Made Easy Interface Object based on Tag
MattyD Posted April 13 Author Posted April 13 (edited) OK thanks! -That's amazing,, I've added those changes in Post #1. yeah the event proc issue's likely going to be a painful one, if its the normal issue we see with callbacks in AutoIt. I remember once solving this by having the script pause its own thread. I found it stopped executing at that point, but the event proc continued to work as per normal. So the "paused" script handled notifications in the background then passed anything it received to a second script via some IPC. As a test, you can pop this after GuiSetState(). Local $aCall = DllCall("kernel32.dll", "dword", "GetCurrentThreadId") Local $iThreadID = $aCall[0] $aCall = DllCall("kernel32.dll", "ptr", "OpenThread", "dword", 0x001F03FF, "int", 0, "dword", $iThreadID) Local $hThread = $aCall[0] DllCall("kernel32.dll", "dword", "SuspendThread", "ptr", $hThread) You should see the notifications happily running. Just be prepared - the window will stop responding and you'll manually need to kill the process. But you should hopefully be able to run the video through. Edited April 13 by MattyD
Nine Posted April 13 Posted April 13 Yep, it does work, the same way you could do : SleepEx(300000, True) Func SleepEx($nMilliseconds, $bAlertable = 0) Local $aRet = DllCall('kernel32.dll', 'dword', 'SleepEx', 'dword', $nMilliseconds, 'bool', $bAlertable) If @error Then Return SetError(@error, @extended, 0) Return $aRet[0] EndFunc ;==>_SleepEx Video is playing normally for the duration of the sleepex MattyD 1 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Debug Messages Monitor UDF Screen Scraping Round Corner GUI UDF Multi-Threading Made Easy Interface Object based on Tag
MattyD Posted April 13 Author Posted April 13 hmm you can use mediaEngine as a frameserver. So it might be worth seeing if we can get another process to do the rendering. Its convoluted, but might be worth a look if there's no better ideas?
Nine Posted April 13 Posted April 13 (edited) I came to the same conclusion. It is quite clear that the rendering is performed into another thread. Since AutoIt is not built to manage multiple threads, it just crashes or gets completely lost. Try this a few times and you will receive all very weird messages : Local $hEvent = _WinAPI_CreateEvent(0, True, False), $iRet While True $iRet = _WinAPI_WaitForSingleObjectEx($hEvent, 1000, True) ConsoleWrite($iRet & @CRLF) WEnd Func _WinAPI_WaitForSingleObjectEx($hEvent, $nMilliseconds, $bAlertable = 0) Local $aRet = DllCall('kernel32.dll', 'dword', 'WaitForSingleObjectEx', 'handle', $hEvent, 'dword', $nMilliseconds, 'bool', $bAlertable) If @error Then Return SetError(@error, @extended, 0) Return $aRet[0] EndFunc ;==>_WinAPI_WaitForSingleObjectEx Edited April 13 by Nine “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Debug Messages Monitor UDF Screen Scraping Round Corner GUI UDF Multi-Threading Made Easy Interface Object based on Tag
MattyD Posted April 14 Author Posted April 14 Hey @CYCho, before we get too carried away - are you able to test your 4k video with what we have so far?
CYCho Posted April 14 Posted April 14 (edited) I first ran your script in your first post with lines 674 through 679 commented. The playback started fine, but the video frames did not seem to move forward and the script stopped after about 5 seconds. I then ran your script with those lines uncommented. Aside from having to use Task Manager to exit the program, the 4k video file played smoothly without any stuttering. Congratulations! Edited April 14 by CYCho zPlayer - A Small Audio and Video Player
UEZ Posted April 14 Posted April 14 Nice work. It crashes for x64 just after displaying GUI : (609,0) IsObj($oIMFMediaEngineNotify) = 1 (648,0) Fact.CreateInstance(), hr = 0x00000000 (650,0) IMFEngine Created = True Test a few notifications.... Event: 22 >, Volume Change, Vol: 1.000000, Muted: True Event: 22 >, Volume Change, Vol: 1.000000, Muted: False Event: 1001 > Purge Queued Events Event: 1 > P1: 0, P2 0 (663,0) $oIMFEngine.SetSource hresult = 0x00000000 Event: 1001 > Purge Queued Events Event: 4 > P1: 0, P2 0 Event: 6 > Emptied Event: 1 > P1: 0, P2 0 (665,0) $oIMFEngine.Load hresult = 0x00000000 Event: 8 > Play Event: 12 > Waiting (667,0) $oIMFEngine.Play hresult = 0x00000000 Event: 21 > P1: 0, P2 0 Event: 10 > P1: 0, P2 0 Event: 11 > P1: 0, P2 0 Event: 14 > CanPlay Event: 15 > P1: 0, P2 0 Event: 18 > Time Update Event: 1000 > P1: 0, P2 0 Event: 1009 > P1: 0, P2 0 Event: 18 > Time Update Event: 18 > Time Update Event: 13 > Playing Event: 18 > Time Update !>09:52:06 AutoIt3.exe ended.rc:-1073741819 -1073741819 / 0xC0000005: An Access Violation is a type of Exception caused when an application Reads, Writes or Executes an invalid Memory Address. x86: it starts but get frozen after 1 sec and crashes with same error as for x64. Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
MattyD Posted April 14 Author Posted April 14 (edited) Thanks guys. I've found if you spin up a MsgBox() and just keep it open, the whole window doesn't lock up. I don't suppose we can block execution in the same way, but without the dialog? If we can achieve this, we might be able to embed the video into a window owned by a child process using $WS_CHILD. Sleeping/Suspending the thread locks up both windows. Edited April 14 by MattyD
Nine Posted April 14 Posted April 14 Good find. I was trying to use one of my IPC to connect both running processes. Even with the MsgBox I am having a hard time to send messages to rendering process. However the Main process can receive quite nicely messages from the rendering process. Along the way I made a small UDF to create interface object, based on our discussion and from a post I saw from trancexx. I also included it in the script. I'll let you decide what you want to do with this version 2 of the engine. MediaEngine.zip CYCho and MattyD 2 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Debug Messages Monitor UDF Screen Scraping Round Corner GUI UDF Multi-Threading Made Easy Interface Object based on Tag
CYCho Posted April 14 Posted April 14 (edited) @MattyD, I found that, with a MsgBox open, the GUI and the video could be minimized, maximaized, and resized. Edited April 14 by CYCho zPlayer - A Small Audio and Video Player
MattyD Posted April 16 Author Posted April 16 Awesome - that's great @Nine. Just trying to do a bit of a tidy up before moving forward, so I've added a header to post #1 which is basically everything in defined "mfmediaengine.h". None of the other headers included in that file are wrapped - we probably don't need them all anyway to be fair! Any constants in there outside of mfmediaengine.h have only been defined so the include works! I've been at one project or another for last few weeks - so I'll take a few days off, and will be back after a bit of a refresh!
MattyD Posted April 18 Author Posted April 18 Ok we're back with a new stuff in post #1. You'll first need to compile "playerDemo_engine.au3", then run "playerDemo.au3". We're still using a modal to block execution in the engine script - wish we could do something nicer, but I guess it'll have to do for now. For comms between processes we're using windows messages (thanks nine for the inspiration!). Look for the $WM_ME* values in the constants file. The WM codes are the same values as those generated by the mediaengine, combined with WM_APP. There's one totally "made up" code - its for MediaEngine to send through its window handle to the UI process ($WM_ME_PLAYBACKWINDOW). Also with the WMs, there's a bit of jiggery pokey in order to pass floating point values over wparam and lparam. I found if you send values as a float or double, they pop out as an integer on the other end - so you lose everything after the decimal point. But sending the values as binary solves this. We just need to ensure we convert our "doubles" to "floats" for x86 so the values fit within wparam/lparam. One last thing... you can still crash the engine by flooding it with messages from the UI, but that's where we're at for now. We could probably fix this by only check incoming messages from within the event handler... Then the problem is the engine won't be contactable when its paused, so you'd need to flick between two modes of checking for messages. And it would also require a total rethink of how to pass comms from the UI back to the engine! argumentum, CYCho, Shark007 and 1 other 4
CYCho Posted Saturday at 11:49 AM Posted Saturday at 11:49 AM On 4/18/2025 at 9:37 AM, MattyD said: We're still using a modal to block execution in the engine script - wish we could do something nicer, but I guess it'll have to do for now. You have all my roots for your success! In the meantime, if it is not so much complicated, could you please move the $sSource definition and $oIMFEngine.Load() function to PlayerDemo.au3, the same way as you did for Play/Pause functions? zPlayer - A Small Audio and Video Player
MattyD Posted Saturday at 02:50 PM Author Posted Saturday at 02:50 PM sure thing , I've updated the example in post #1. CYCho 1
argumentum Posted Saturday at 03:26 PM Posted Saturday at 03:26 PM $sSource = FileOpenDialog("Open Media", @ScriptDir & "\", "Video Files (*.mp4;*.m4v;*.mpg;*.wmv;*.mov;*.mkv)|Audio Files (*.mp3;*.aac;*.m4a;*.wma)", $FD_FILEMUSTEXIST) mkv files play too. The FWD is audio only but it plays CYCho 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
MattyD Posted Saturday at 03:35 PM Author Posted Saturday at 03:35 PM haha, yeah I'm bound to have missed a bunch of formats. I'll fix up my end so It'll make the next upload argumentum and CYCho 2
argumentum Posted Saturday at 03:38 PM Posted Saturday at 03:38 PM 2 minutes ago, MattyD said: I'm bound to have missed a bunch of formats. $sSource = FileOpenDialog("Open Media", @ScriptDir & "\", "Video Files (*.mp4;*.m4v;*.mpg;*.wmv;*.mov;*.mkv)" & _ "|Audio Files (*.mp3;*.aac;*.m4a;*.wma)|Good luck (*.*)", $FD_FILEMUSTEXIST) If Not FileExists($sSource) Then ContinueLoop MattyD and CYCho 1 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
CYCho Posted Sunday at 02:35 PM Posted Sunday at 02:35 PM The first pass of Load and Play works fine. But I cannot seem to be able to load and play the next file. I tried to load another file after the end of playback of the first file, or after "Stop" of the first file, and failed in both cases with an error message saying "Variable used without being declared." I could load and play the second file while the first file was playing, but I couldn't load the third file while the second was playing. I don't think you need to spend time to fix this becuase I believe this will be fixed when you solve the need for a modal block. zPlayer - A Small Audio and Video Player
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now