Blog. Just Blog

Мультимедийный плеер на Ассемблере

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Мультимедийный плеер на Ассемблере
Мультимедийный плеер на Ассемблере

Сегодня будем программировать нечто действительно интересное, а именно универсальный мультимедийный плеер. Универсальность реализуется мощью функционала DirectShow, а также установленными в системе аудио- и видеокодеками. И пусть это не полноценное приложение, большинство основных функций плеера в нем будут реализованы.

Сперва, как обычно, нам понадобится здоровенная пачка различных GUID'ов, интерфейсов и констант. Значение CLSID_FilterGraph почему-то даже не описано в SDK, пришлось покопаться в интернетах.
  1. ; GUID {E436EBB3-524F-11CE-9F53-0020AF0BA770}
  2. CLSID_FilterGraph \
  3.     dd 0E436EBB3h
  4.     dw 0524Fh
  5.     dw 011CEh
  6.     db 09Fh, 053h, 000h, 020h, 0AFh, 00Bh, 0A7h, 070h
  7.  
  8. ; GUID {56A868A9-0AD4-11CE-B03A-0020AF0BA770}
  9. IID_IGraphBuilder \
  10.     dd 056A868A9h
  11.     dw 00AD4h
  12.     dw 011CEh
  13.     db 0B0h, 03Ah, 000h, 020h, 0AFh, 00Bh, 0A7h, 070h
  14.  
  15. ; IID_IGraphBuilder Interface
  16. struct IGraphBuilder
  17.     ; IUnknown
  18.     QueryInterface          dd ?   ; 000h
  19.     AddRef                  dd ?   ; 004h
  20.     Release                 dd ?   ; 008h
  21.     ; IGraphBuilder
  22.     AddFilter               dd ?   ; 00Ch
  23.     RemoveFilter            dd ?   ; 010h
  24.     EnumFilters             dd ?   ; 014h
  25.     FindFilterByName        dd ?   ; 018h
  26.     ConnectDirect           dd ?   ; 01Ch
  27.     Reconnect               dd ?   ; 020h
  28.     Disconnect              dd ?   ; 024h
  29.     SetDefaultSyncSource    dd ?   ; 028h
  30.     Connect                 dd ?   ; 02Ch
  31.     Render                  dd ?   ; 030h
  32.     RenderFile              dd ?   ; 034h
  33.     AddSourceFilter         dd ?   ; 038h
  34.     SetLogFile              dd ?   ; 03Ch
  35.     Abort                   dd ?   ; 040h
  36.     ShouldOperationContinue dd ?   ; 044h
  37. ends
  38.  
  39. ; GUID {56A868B1-0AD4-11CE-B03A-0020AF0BA770}
  40. IID_IMediaControl \
  41.     dd 056A868B1h
  42.     dw 00AD4h
  43.     dw 011CEh
  44.     db 0B0h, 03Ah, 000h, 020h, 0AFh, 00Bh, 0A7h, 070h
  45.  
  46. ; IID_IMediaControl Interface
  47. struct IMediaControl
  48.     ; IUnknown
  49.     QueryInterface          dd ?   ; 000h
  50.     AddRef                  dd ?   ; 004h
  51.     Release                 dd ?   ; 008h
  52.     ; IMediaControl
  53.     GetTypeInfoCount        dd ?   ; 00Ch
  54.     GetTypeInfo             dd ?   ; 010h
  55.     GetIDsOfNames           dd ?   ; 014h
  56.     _Invoke                 dd ?   ; 018h
  57.     Run                     dd ?   ; 01Ch
  58.     Pause                   dd ?   ; 020h
  59.     Stop                    dd ?   ; 024h
  60.     GetState                dd ?   ; 028h
  61.     RenderFile              dd ?   ; 02Ch
  62.     AddSourceFilter         dd ?   ; 030h
  63.     get_FilterCollection    dd ?   ; 034h
  64.     get_RegFilterCollection dd ?   ; 038h
  65.     StopWhenReady           dd ?   ; 03Ch
  66. ends
  67.  
  68. ; GUID {56A868B4-0AD4-11CE-B03A-0020AF0BA770}
  69. IID_IVideoWindow \
  70.     dd 056A868B4h
  71.     dw 00AD4h
  72.     dw 011CEh
  73.     db 0B0h, 03Ah, 000h, 020h, 0AFh, 00Bh, 0A7h, 070h
  74.  
  75. ; IID_IVideoWindow Interface
  76. struct IVideoWindow
  77.     ; IUnknown
  78.     QueryInterface        dd ?   ; 000h
  79.     AddRef                dd ?   ; 004h
  80.     Release               dd ?   ; 008h
  81.     ; IVideoWindow
  82.     GetTypeInfoCount      dd ?   ; 00Ch
  83.     GetTypeInfo           dd ?   ; 010h
  84.     GetIDsOfNames         dd ?   ; 014h
  85.     _Invoke               dd ?   ; 018h
  86.     put_Caption           dd ?   ; 01Ch
  87.     get_Caption           dd ?   ; 020h
  88.     put_WindowStyle       dd ?   ; 024h
  89.     get_WindowStyle       dd ?   ; 028h
  90.     put_WindowStyleEx     dd ?   ; 02Ch
  91.     get_WindowStyleEx     dd ?   ; 030h
  92.     put_AutoShow          dd ?   ; 034h
  93.     get_AutoShow          dd ?   ; 038h
  94.     put_WindowState       dd ?   ; 03Ch
  95.     get_WindowState       dd ?   ; 040h
  96.     put_BackgroundPalette dd ?   ; 044h
  97.     get_BackgroundPalette dd ?   ; 048h
  98.     put_Visible           dd ?   ; 04Ch
  99.     get_Visible           dd ?   ; 050h
  100.     put_Left              dd ?   ; 054h
  101.     get_Left              dd ?   ; 058h
  102.     put_Width             dd ?   ; 05Ch
  103.     get_Width             dd ?   ; 060h
  104.     put_Top               dd ?   ; 064h
  105.     get_Top               dd ?   ; 068h
  106.     put_Height            dd ?   ; 06Ch
  107.     get_Height            dd ?   ; 070h
  108.     put_Owner             dd ?   ; 074h
  109.     get_Owner             dd ?   ; 078h
  110.     put_MessageDrain      dd ?   ; 07Ch
  111.     get_MessageDrain      dd ?   ; 080h
  112.     get_BorderColor       dd ?   ; 084h
  113.     put_BorderColor       dd ?   ; 088h
  114.     get_FullScreenMode    dd ?   ; 08Ch
  115.     put_FullScreenMode    dd ?   ; 090h
  116.     SetWindowForeground   dd ?   ; 094h
  117.     NotifyOwnerMessage    dd ?   ; 098h
  118.     SetWindowPosition     dd ?   ; 09Ch
  119.     GetWindowPosition     dd ?   ; 0A0h
  120.     GetMinIdealImageSize  dd ?   ; 0A4h
  121.     GetMaxIdealImageSize  dd ?   ; 0A8h
  122.     GetRestorePosition    dd ?   ; 0ACh
  123.     HideCursor            dd ?   ; 0B0h
  124.     IsCursorHidden        dd ?   ; 0B4h
  125. ends
  126.  
  127. ; GUID {36B73880-C2C8-11CF-8B46-00805F6CEF60}
  128. IID_IMediaSeeking \
  129.     dd 036B73880h
  130.     dw 0C2C8h
  131.     dw 011CFh
  132.     db 08Bh, 046h, 000h, 080h, 05Fh, 06Ch, 0EFh, 060h
  133.  
  134. ; IID_IMediaSeeking Interface
  135. struct IMediaSeeking
  136.     ; IUnknown
  137.     QueryInterface       dd ?   ; 000h
  138.     AddRef               dd ?   ; 004h
  139.     Release              dd ?   ; 008h
  140.     ; IMediaSeeking
  141.     GetCapabilities      dd ?   ; 00Ch
  142.     CheckCapabilities    dd ?   ; 010h
  143.     IsFormatSupported    dd ?   ; 014h
  144.     QueryPreferredFormat dd ?   ; 018h
  145.     GetTimeFormat        dd ?   ; 01Ch
  146.     IsUsingTimeFormat    dd ?   ; 020h
  147.     SetTimeFormat        dd ?   ; 024h
  148.     GetDuration          dd ?   ; 028h
  149.     GetStopPosition      dd ?   ; 02Ch
  150.     GetCurrentPosition   dd ?   ; 030h
  151.     ConvertTimeFormat    dd ?   ; 034h
  152.     SetPositions         dd ?   ; 038h
  153.     GetPositions         dd ?   ; 03Ch
  154.     GetAvailable         dd ?   ; 040h
  155.     SetRate              dd ?   ; 044h
  156.     GetRate              dd ?   ; 048h
  157.     GetPreroll           dd ?   ; 04Ch
  158. ends
  159.  
  160. ; GUID {56A868C0-0AD4-11CE-B03A-0020AF0BA770}
  161. IID_IMediaEventEx \
  162.     dd 056A868C0h
  163.     dw 00AD4h
  164.     dw 011CEh
  165.     db 0B0h, 03Ah, 000h, 020h, 0AFh, 00Bh, 0A7h, 070h
  166.  
  167. ; IID_IMediaEventEx Interface
  168. struct IMediaEventEx
  169.     ; IUnknown
  170.     QueryInterface         dd ?   ; 000h
  171.     AddRef                 dd ?   ; 004h
  172.     Release                dd ?   ; 008h
  173.     ; IMediaEventEx
  174.     GetTypeInfoCount       dd ?   ; 00Ch
  175.     GetTypeInfo            dd ?   ; 010h
  176.     GetIDsOfNames          dd ?   ; 014h
  177.     _Invoke                dd ?   ; 018h
  178.     GetEventHandle         dd ?   ; 01Ch
  179.     GetEvent               dd ?   ; 020h
  180.     WaitForCompletion      dd ?   ; 024h
  181.     CancelDefaultHandling  dd ?   ; 028h
  182.     RestoreDefaultHandling dd ?   ; 02Ch
  183.     FreeEventParams        dd ?   ; 030h
  184.     SetNotifyWindow        dd ?   ; 034h
  185.     SetNotifyFlags         dd ?   ; 038h
  186.     GetNotifyFlags         dd ?   ; 03Ch
  187. ends
  188.  
  189. ; GUID {56A868B5-0AD4-11CE-B03A-0020AF0BA770}
  190. IID_IBasicVideo \
  191.     dd 056A868B5h
  192.     dw 00AD4h
  193.     dw 011CEh
  194.     db 0B0h, 03Ah, 000h, 020h, 0AFh, 00Bh, 0A7h, 070h
  195.  
  196. ; IID_IBasicVideo Interface
  197. struct IBasicVideo
  198.     ; IUnknown
  199.     QueryInterface                dd ?   ; 000h
  200.     AddRef                        dd ?   ; 004h
  201.     Release                       dd ?   ; 008h
  202.     ; IBasicVideo
  203.     GetTypeInfoCount              dd ?   ; 00Ch
  204.     GetTypeInfo                   dd ?   ; 010h
  205.     GetIDsOfNames                 dd ?   ; 014h
  206.     _Invoke                       dd ?   ; 018h
  207.     get_AvgTimePerFrame           dd ?   ; 01Ch
  208.     get_BitRate                   dd ?   ; 020h
  209.     get_BitErrorRate              dd ?   ; 024h
  210.     get_VideoWidth                dd ?   ; 028h
  211.     get_VideoHeight               dd ?   ; 02Ch
  212.     put_SourceLeft                dd ?   ; 030h
  213.     get_SourceLeft                dd ?   ; 034h
  214.     put_SourceWidth               dd ?   ; 038h
  215.     get_SourceWidth               dd ?   ; 03Ch
  216.     put_SourceTop                 dd ?   ; 040h
  217.     get_SourceTop                 dd ?   ; 044h
  218.     put_SourceHeight              dd ?   ; 048h
  219.     get_SourceHeight              dd ?   ; 04Ch
  220.     put_DestinationLeft           dd ?   ; 050h
  221.     get_DestinationLeft           dd ?   ; 054h
  222.     put_DestinationWidth          dd ?   ; 058h
  223.     get_DestinationWidth          dd ?   ; 05Ch
  224.     put_DestinationTop            dd ?   ; 060h
  225.     get_DestinationTop            dd ?   ; 064h
  226.     put_DestinationHeight         dd ?   ; 068h
  227.     get_DestinationHeight         dd ?   ; 06Ch
  228.     SetSourcePosition             dd ?   ; 070h
  229.     GetSourcePosition             dd ?   ; 074h
  230.     SetDefaultSourcePosition      dd ?   ; 078h
  231.     SetDestinationPosition        dd ?   ; 07Ch
  232.     GetDestinationPosition        dd ?   ; 080h
  233.     SetDefaultDestinationPosition dd ?   ; 084h
  234.     GetVideoSize                  dd ?   ; 088h
  235.     GetVideoPaletteEntries        dd ?   ; 08Ch
  236.     GetCurrentImage               dd ?   ; 090h
  237.     IsUsingDefaultSource          dd ?   ; 094h
  238.     IsUsingDefaultDestination     dd ?   ; 098h
  239. ends
  240.  
  241. CLSCTX_INPROC_SERVER = 0x1
  242. WM_APP = 0x8000
  243. WM_GRAPHNOTIFY = WM_APP + 1
  244. EC_COMPLETE = 0x01
  245. AM_SEEKING_AbsolutePositioning = 0x1
  246.  
  247. State_Stopped = 0
  248. State_Paused = 1
  249. State_Running = 2
После стандартной инициализации COM, надо подключить основной мультимедийный модуль - интерфейс IGraphBuilder. На сайте MSDN указано, что это типа устаревшая технология, но зато она работает, начиная аж с Windows 2000 и по сегодняшний день. Поэтому не вижу смысла гоняться за чем-то иным только ради обслуживания новомодных говносистем. Получив интерфейс IGraphBuilder, с помощью метода QueryInterface получаем интерфейсы для управления медиапотоками, окнами для видео, перемоткой и т.п. Практически каждое действие завязано на собственный интерфейс.
  1.         ; Инициализация всех интерфейсов
  2.         invoke  CoCreateInstance,CLSID_FilterGraph,NULL,\
  3.                 CLSCTX_INPROC_SERVER,IID_IGraphBuilder,\
  4.                 pGraphBuilder
  5.  
  6.         mov     eax, [pGraphBuilder]
  7.         mov     eax, [eax]
  8.         stdcall dword [eax+IGraphBuilder.QueryInterface],[pGraphBuilder],\
  9.                 IID_IMediaControl,pMediaControl
  10.  
  11.         mov     eax, [pGraphBuilder]
  12.         mov     eax, [eax]
  13.         stdcall dword [eax+IGraphBuilder.QueryInterface],[pGraphBuilder],\
  14.                 IID_IVideoWindow,pVideoWindow
  15.  
  16.         mov     eax, [pGraphBuilder]
  17.         mov     eax, [eax]
  18.         stdcall dword [eax+IGraphBuilder.QueryInterface],[pGraphBuilder],\
  19.                 IID_IMediaSeeking,pMediaSeeking
  20.  
  21.         mov     eax, [pGraphBuilder]
  22.         mov     eax, [eax]
  23.         stdcall dword [eax+IGraphBuilder.QueryInterface],[pGraphBuilder],\
  24.                 IID_IMediaEventEx,pEvent
  25.  
  26.         mov     eax, [pGraphBuilder]
  27.         mov     eax, [eax]
  28.         stdcall dword [eax+IGraphBuilder.QueryInterface],[pGraphBuilder],\
  29.                 IID_IBasicVideo,pBasicVideo
Файл для воспроизведения загружается при помощи метода RenderFile. Путь к файлу обязательно должен быть в юникоде. На этом этапе уже можно определить, сможет ли плеер в принципе воспроизвести этот файл или нет. Как я упомянул в начале статьи, это зависит от установленных в системе кодеков. Всю грязную работу типа выделения памяти система берет на себя.
  1.         ; Загрузить файл для воспроизведения
  2.         mov     eax, [pGraphBuilder]
  3.         mov     eax, [eax]
  4.         stdcall dword [eax+IGraphBuilder.RenderFile],[pGraphBuilder],\
  5.                 path,NULL
На следующем этапе надо подготовить окно для воспроизведения видео. Если этого не сделать, то будет создано отдельное окно. Нам же надо, чтобы видео воспроизводилось в интерфейсе нашего приложения. Это может быть, например, обычный STATIC или даже EDIT.
  1.         ; Назначить окно для воспроизведения видео
  2.         invoke  GetDlgItem,[hwnddlg],ID_VIDEO
  3.         mov     ebx,eax
  4.  
  5.         mov     eax, [pVideoWindow]
  6.         mov     eax, [eax]
  7.         stdcall dword [eax+IVideoWindow.put_Owner],[pVideoWindow],\
  8.                 ebx
  9.  
  10.         mov     eax, [pBasicVideo]
  11.         mov     eax, [eax]
  12.         stdcall dword [eax+IBasicVideo.get_VideoWidth],[pBasicVideo],\
  13.                 pWidth
  14.  
  15.         mov     eax, [pBasicVideo]
  16.         mov     eax, [eax]
  17.         stdcall dword [eax+IBasicVideo.get_VideoHeight],[pBasicVideo],\
  18.                 pHeight
  19.  
  20.         cmp     [pWidth],IMG_X
  21.         jae     loc_need_resize
  22.         cmp     [pHeight],IMG_Y
  23.         jbe     loc_create_video
  24. loc_need_resize:
  25.         ; Пресчет размеров по горизонтали
  26.         mov     eax,[pWidth]
  27.         cmp     eax,[pHeight]
  28.         jae     @f
  29.  
  30.         mov     eax,[pWidth]
  31.         xor     edx,edx
  32.         mov     ecx,IMG_Y
  33.         imul    ecx
  34.         xor     edx,edx
  35.         mov     ecx,[pHeight]
  36.         idiv    ecx
  37.         mov     [pWidth],eax
  38.         mov     [pHeight],IMG_Y
  39.         jmp     loc_create_video
  40. @@:
  41.         mov     eax,[pHeight]
  42.         xor     edx,edx
  43.         mov     ecx,IMG_X
  44.         imul    ecx
  45.         xor     edx,edx
  46.         mov     ecx,[pWidth]
  47.         idiv    ecx
  48.         mov     [pHeight],eax
  49.         mov     [pWidth],IMG_X
  50. loc_create_video:
  51.         mov     [deltaX],0
  52.         mov     [deltaY],0
  53.  
  54.         ; Смещение по X
  55.         cmp     [pWidth],IMG_X
  56.         jae     @f
  57.         mov     eax,IMG_X
  58.         sub     eax,[pWidth]
  59.         shr     eax,1
  60.         mov     [deltaX],eax
  61. @@:
  62.         ; Смещение по Y
  63.         cmp     [pHeight],IMG_Y
  64.         jae     @f
  65.         mov     eax,IMG_Y
  66.         sub     eax,[pHeight]
  67.         shr     eax,1
  68.         mov     [deltaY],eax
  69. @@:
  70.         ; Установить стиль окна
  71.         mov     eax, [pVideoWindow]
  72.         mov     eax, [eax]
  73.         stdcall dword [eax+IVideoWindow.put_WindowStyle],[pVideoWindow],\
  74.                 WS_CHILD+WS_CLIPSIBLINGS
  75.  
  76.         ; Установить размер области воспроизведения
  77.         mov     eax, [pVideoWindow]
  78.         mov     eax, [eax]
  79.         stdcall dword [eax+IVideoWindow.SetWindowPosition],[pVideoWindow],\
  80.                 [deltaX],[deltaY],[pWidth],[pHeight]
  81.  
  82.         ; Назначить окно для событий плеера
  83.         mov     eax, [pEvent]
  84.         mov     eax, [eax]
  85.         stdcall dword [eax+IMediaEventEx.SetNotifyWindow],[pEvent],\
  86.                 [hwnddlg],WM_GRAPHNOTIFY,NULL ; [hwnddlg]
  87.  
  88.         ; Заблокировать окно воспроизведения
  89.         invoke  EnableWindow,ebx,FALSE
Несколько моментов. Константы IMG_X и IMG_Y - это размеры области, в которой будет воспроизводиться видео. При помощи методов get_VideoWidth и get_VideoHeight получаем размеры видеокадра и масштабируем их в границах области воспроизведения. Дальше надо назначить окно, которое будет получать уведомление WM_GRAPHNOTIFY от графического фильтра. Еще один интересный момент, что приходится обязательно дизаблить область воспроизведения, иначе при клике на видео все приложение наглухо замирает. Объяснения этому я не нашел, может быть кто-нибудь из более опытных коллег прояснит подобное странное поведение.

Осталось только запустить файл на воспроизведение. Делается это при помощи метода Run управляющего интерфейса IMediaControl.
  1.         ; Запустить видео
  2.         mov     eax, [pMediaControl]
  3.         mov     eax, [eax]
  4.         stdcall dword [eax+IMediaControl.Run],[pMediaControl]
Управлять воспроизведением можно при помощи еще двух методов, это Pause и Stop.
  1.         ; Поставить видео на паузу
  2.         mov     eax, [pMediaControl]
  3.         mov     eax, [eax]
  4.         stdcall dword [eax+IMediaControl.Pause],[pMediaControl]
  1.         ; Остановить видео
  2.         mov     eax, [pMediaControl]
  3.         mov     eax, [eax]
  4.         stdcall dword [eax+IMediaControl.Stop],[pMediaControl]
Получить текущее состояние воспроизведения можно при помощи метода GetState. Возможные значения состояния это "пауза", "стоп" и "воспроизведение".
  1.         ; Получить состояние воспроизведения
  2.         mov     eax, [pMediaControl]
  3.         mov     eax, [eax]
  4.         stdcall dword [eax+IMediaControl.GetState],[pMediaControl],\
  5.                 0,pState
Интерфейс IMediaSeeking позволяет получить информацию о длительности медиафайла, о текущей позиции воспроизведения, а также с его помощью можно эту самую позицию передвинуть.
  1.         ; Получить длительность медиафайла
  2.         mov     eax, [pMediaSeeking]
  3.         mov     eax, [eax]
  4.         stdcall dword [eax+IMediaSeeking.GetDuration],[pMediaSeeking],\
  5.                 lDuration
  1.         ; Получить текущую позицию воспроизведения
  2.         mov     eax, [pMediaSeeking]
  3.         mov     eax, [eax]
  4.         stdcall dword [eax+IMediaSeeking.GetPositions],[pMediaSeeking],\
  5.                 lDuration,pStop
  1.         ; Перемотать поток на начало
  2.         mov     dword[lDuration],0
  3.         mov     dword[lDuration+4],0
  4.  
  5.         mov     eax, [pMediaSeeking]
  6.         mov     eax, [eax]
  7.         stdcall dword [eax+IMediaSeeking.SetPositions],[pMediaSeeking],\
  8.                 lDuration,AM_SEEKING_AbsolutePositioning,\
  9.                 lDuration,0
Длительность хранится в QWORD выражается в сотнях наносекунд, поэтому для перевода значения в более привычные секунды это значение надо поделить на 10000000. При установке позиции воспроизведения, соответственно, надо привести человекопонятное значение в эти же сотни наносекунд с помощью умножения.

В зависимости от тех или иных условий, графический фильтр может посылать сообщение WM_GRAPHNOTIFY назначенному ранее окну. Обработчик этого сообщения выглядит примерно следующим образом:
  1.         cmp     [msg],WM_GRAPHNOTIFY
  2.         je      wmgraph
  3.         ...
  4.         ...
  5. wmgraph:
  6.         ; Получить событие из очереди
  7.         mov     eax, [pEvent]
  8.         mov     eax, [eax]
  9.         stdcall dword [eax+IMediaEventEx.GetEvent],[pEvent],\
  10.                 evCode, param1, param2, NULL
  11.         or      eax,eax
  12.         ; Событий в очереди больше нет
  13.         jnz     processed
  14.  
  15.         ; Освободить событие
  16.         mov     eax, [pEvent]
  17.         mov     eax, [eax]
  18.         stdcall dword [eax+IMediaEventEx.FreeEventParams],[pEvent],\
  19.                 [evCode],[param1],[param2]
  20.  
  21.         ; Воспроизведение завершено?
  22.         cmp     [evCode],EC_COMPLETE
  23.         jne     @f
  24.         ...
  25.         ; Действия по завершению воспроизведения
  26.         ...
  27. @@:
  28.         ; Обработать следующее сообщение
  29.         jmp     wmgraph
При завершении работы надо освободить выделенные ресурсы. Здесь единственный момент, на который стоит обратить внимание, заключается в том, что перед релизом интерфейса событий надо отвязать окно, получающее уведомления графического фильтра.
  1.         ; Прибраться за собой
  2.         mov     eax, [pEvent]
  3.         mov     eax, [eax]
  4.         stdcall dword [eax+IMediaEventEx.SetNotifyWindow],[pEvent],\
  5.                 NULL,NULL,NULL
  6.  
  7.         mov     eax, [pEvent]
  8.         mov     eax, [eax]
  9.         stdcall dword [eax+IMediaEventEx.Release],[pEvent]
  10.  
  11.         mov     eax, [pBasicVideo]
  12.         mov     eax, [eax]
  13.         stdcall dword [eax+IBasicVideo.Release],[pBasicVideo]
  14.  
  15.         mov     eax, [pVideoWindow]
  16.         mov     eax, [eax]
  17.         stdcall dword [eax+IVideoWindow.Release],[pVideoWindow]
  18.  
  19.         mov     eax, [pMediaControl]
  20.         mov     eax, [eax]
  21.         stdcall dword [eax+IMediaControl.Release],[pMediaControl]
  22.  
  23.         mov     eax, [pMediaSeeking]
  24.         mov     eax, [eax]
  25.         stdcall dword [eax+IMediaSeeking.Release],[pMediaSeeking]
  26.  
  27.         mov     eax, [pGraphBuilder]
  28.         mov     eax, [eax]
  29.         stdcall dword [eax+IGraphBuilder.Release],[pGraphBuilder]
Всего вышеперечисленного уже должно хватить для реализации мультимедийного плеера. Получаем файл, проверяем его на поддерживаемый формат, готовим область воспроизведения, запускаем. По каким-нибудь кнопочкам выполняем паузу и воспроизведение, по таймеру отслеживаем позицию воспроизведения и каким-либо образом отображаем это в интерфейсе приложения. Что классно, воспроизведение видео и аудио производится вообще без изменения кода.

В приложении пример программы с исходным текстом, которая воспроизводит видеофайл из архива.

Пример программы с исходным текстом (FASM)Пример программы с исходным текстом (FASM)

Multimedia.Player.Demo.zip (1,134,866 bytes)


Поделиться ссылкой ВКонтакте
Просмотров: 349 | Комментариев: 4

Комментарии

Отзывы посетителей сайта о статье
ManHunter (02.05.2024 в 13:57):
Mikl___, поддерживает не плеер, а система. Нет кодеков - нет поддержки, есть кодеки - поддерживает. У меня с установленным k-lite megapack крутит даже flv.

Тем более, что это ни в коем случае не полноценное приложение, а только каркас. Никаких проверок не делается, никакой диагностики не выводится.
Mikl___ (02.05.2024 в 13:52):
ManHunter, а mp4 ваш плейер поддерживает? Вклад в общую копилку -- посмотрите у меня в "Сказках дядюшки Римуса о x64" 52-ую главу "Братец Кролик и просмотр видео-файлов". Там россыпь разных видео-плейеров с исходным текстом и экзе
ManHunter (26.04.2024 в 11:51):
Проверено на Win7x86, Win7x64, Win10x86, Win10x64, все прекрасно работает.
User (26.04.2024 в 10:14):
как заставить воспроизводить файл из архива, или любой другой? При запуске рядом с файлом не воспроизводит. drug-n-drop не поддерживается. Через открыть как тоже

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.06 сек. / MySQL: 2 (0.0033 сек.) / Память: 4.5 Mb
Наверх