User Tools

Site Tools


playing_20a_20media_20file_20using_20direct_20show

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

playing_20a_20media_20file_20using_20direct_20show [2018/03/31 13:19]
127.0.0.1 external edit
playing_20a_20media_20file_20using_20direct_20show [2018/04/15 13:03] (current)
richardrussell Added syntax highlighting
Line 1: Line 1:
 =====Playing a media file using Direct Show===== =====Playing a media file using Direct Show=====
  
-//by Richard Russell, December 2007//\\ \\  Windows provides several methods for playing audio and video files. One of the simplest is the Media Control Interface (MCI) which is used by //BBC BASIC for Windows// to play MIDI files and is also the basis of the **PLAYER.BBC** media player application which can be found [[http://​www.bbcbasic.co.uk/​bbcwin/​examples/​player.html|here]]. However, whilst MCI is easy to use it does not support some file formats such as **animated GIFs**.\\ \\  An alternative is to use **Direct Show** (a subset of the DirectX system). This is not as straightforward as **MCI** in terms of code, but it may support a wider range of file formats. This article describes the simplest use of Direct Show to play an audio or video file.\\ \\  Firstly we need to perform some initialisation:​\\ \\ +//by Richard Russell, December 2007//\\ \\  Windows provides several methods for playing audio and video files. One of the simplest is the Media Control Interface (MCI) which is used by //BBC BASIC for Windows// to play MIDI files and is also the basis of the **PLAYER.BBC** media player application which can be found [[http://​www.bbcbasic.co.uk/​bbcwin/​examples/​player.html|here]]. However, whilst MCI is easy to use it does not support some file formats such as **animated GIFs**.\\ \\  An alternative is to use **Direct Show** (a subset of the DirectX system). This is not as straightforward as **MCI** in terms of code, but it may support a wider range of file formats. This article describes the simplest use of Direct Show to play an audio or video file.\\ \\  Firstly we need to perform some initialisation:​ 
 + 
 +<code bb4w> ​
         SYS "​LoadLibrary",​ "​OLE32.DLL"​ TO ole32%         SYS "​LoadLibrary",​ "​OLE32.DLL"​ TO ole32%
         SYS "​GetProcAddress",​ ole32%, "​CoInitialize" ​    TO `CoInitialize`         SYS "​GetProcAddress",​ ole32%, "​CoInitialize" ​    TO `CoInitialize`
Line 8: Line 10:
         SYS "​GetProcAddress",​ ole32%, "​CLSIDFromString" ​ TO `CLSIDFromString`         SYS "​GetProcAddress",​ ole32%, "​CLSIDFromString" ​ TO `CLSIDFromString`
         SYS `CoInitialize`,​ 0         SYS `CoInitialize`,​ 0
-To ensure the necessary 'clean up' operations are carried out on exit the program should include **ON ERROR** and **ON CLOSE** statements:\\ \\ +</​code>​ 
 + 
 +To ensure the necessary 'clean up' operations are carried out on exit the program should include **ON ERROR** and **ON CLOSE** statements: 
 + 
 +<code bb4w>
         ON ERROR PROCcleanup : SYS "​MessageBox",​ @hwnd%, REPORT$, 0, 48 : QUIT         ON ERROR PROCcleanup : SYS "​MessageBox",​ @hwnd%, REPORT$, 0, 48 : QUIT
         ON CLOSE PROCcleanup : QUIT         ON CLOSE PROCcleanup : QUIT
-The next step is to //​instantiate//​ the **filter graph manager**:\\ \\ +</​code>​ 
 + 
 +The next step is to //​instantiate//​ the **filter graph manager**: 
 + 
 +<code bb4w>
         CLSID_FilterGraph% = FNguid("​{e436ebb3-524f-11ce-9f53-0020af0ba770}"​)         CLSID_FilterGraph% = FNguid("​{e436ebb3-524f-11ce-9f53-0020af0ba770}"​)
         IID_IGraphBuilder% = FNguid("​{56a868a9-0ad4-11ce-b03a-0020af0ba770}"​)         IID_IGraphBuilder% = FNguid("​{56a868a9-0ad4-11ce-b03a-0020af0ba770}"​)
Line 19: Line 29:
         \                       ​IID_IGraphBuilder%,​ ^m_graphBuilder% TO hr%         \                       ​IID_IGraphBuilder%,​ ^m_graphBuilder% TO hr%
         IF hr% THEN ERROR 100, "Could not create filter graph manager"​         IF hr% THEN ERROR 100, "Could not create filter graph manager"​
-Once the filter graph manager COM object is instantiated we can use it to create two other DirectShow objects, firstly a **media control object**:\\ \\ +</​code>​ 
 + 
 +Once the filter graph manager COM object is instantiated we can use it to create two other DirectShow objects, firstly a **media control object**: 
 + 
 +<code bb4w>
         IID_IMediaControl% = FNguid("​{56a868b1-0ad4-11ce-b03a-0020af0ba770}"​)         IID_IMediaControl% = FNguid("​{56a868b1-0ad4-11ce-b03a-0020af0ba770}"​)
  
         SYS !(!m_graphBuilder%),​ m_graphBuilder%,​ IID_IMediaControl%,​ ^m_mediaControl% TO hr%         SYS !(!m_graphBuilder%),​ m_graphBuilder%,​ IID_IMediaControl%,​ ^m_mediaControl% TO hr%
         IF hr% THEN ERROR 100, "Could not instantiate media control object"​         IF hr% THEN ERROR 100, "Could not instantiate media control object"​
-and secondly a **media event object**:\\ \\ +</​code>​ 
 + 
 +and secondly a **media event object**: 
 + 
 +<code bb4w>
         IID_IMediaEvent% = FNguid("​{56a868b6-0ad4-11ce-b03a-0020af0ba770}"​)         IID_IMediaEvent% = FNguid("​{56a868b6-0ad4-11ce-b03a-0020af0ba770}"​)
  
         SYS !(!m_graphBuilder%),​ m_graphBuilder%,​ IID_IMediaEvent%,​ ^m_mediaEvent% TO hr%         SYS !(!m_graphBuilder%),​ m_graphBuilder%,​ IID_IMediaEvent%,​ ^m_mediaEvent% TO hr%
         IF hr% THEN ERROR 100, "Could not instantiate media event object"​         IF hr% THEN ERROR 100, "Could not instantiate media event object"​
-If the above code succeeded we now have all three Direct Show objects required to handle streamed audio or video playback.\\ \\  To play a file we need to create a **filter graph**:\\ \\ +</​code>​ 
 + 
 +If the above code succeeded we now have all three Direct Show objects required to handle streamed audio or video playback.\\ \\  To play a file we need to create a **filter graph**: 
 + 
 +<code bb4w>
         SYS !(!m_mediaControl%+44),​ m_mediaControl%,​ FNwide(mediafile$),​ 0 TO hr% : REM Render()         SYS !(!m_mediaControl%+44),​ m_mediaControl%,​ FNwide(mediafile$),​ 0 TO hr% : REM Render()
         IF hr% THEN ERROR 100, "Could not render file "​+mediafile$         IF hr% THEN ERROR 100, "Could not render file "​+mediafile$
-Here **mediafile$** should be a fully-qualified path and filename of the file to be played.\\ \\  Now everything is ready to play the file:\\ \\ +</​code>​ 
 + 
 +Here **mediafile$** should be a fully-qualified path and filename of the file to be played.\\ \\  Now everything is ready to play the file: 
 + 
 +<code bb4w>
         SYS !(!m_mediaControl%+28),​ m_mediaControl% TO hr% : REM Run()         SYS !(!m_mediaControl%+28),​ m_mediaControl% TO hr% : REM Run()
  
Line 40: Line 66:
           SYS !(!m_mediaEvent%+36),​ m_mediaEvent%,​ timeout%, ^pEvCode% : REM Wait           SYS !(!m_mediaEvent%+36),​ m_mediaEvent%,​ timeout%, ^pEvCode% : REM Wait
         UNTIL pEvCode%         UNTIL pEvCode%
-You can carry out other operations while the file is playing by including them in the above waiting loop.\\ \\  To play another file, you should release the three objects as in **PROCcleanup** below (but //not// call **CoUninitialize**) and then instantiate the three objects again starting with the filter graph manager. It is preferable to call **CoInitialize** just once at the very start of the program, and **CoUninitialize** just once on exit.\\ \\  Before exiting the program you should call the 'clean up' routine: ​\\ \\ +</​code>​ 
 + 
 +You can carry out other operations while the file is playing by including them in the above waiting loop.\\ \\  To play another file, you should release the three objects as in **PROCcleanup** below (but //not// call **CoUninitialize**) and then instantiate the three objects again starting with the filter graph manager. It is preferable to call **CoInitialize** just once at the very start of the program, and **CoUninitialize** just once on exit.\\ \\  Before exiting the program you should call the 'clean up' routine: 
 + 
 +<code bb4w>
         PROCcleanup         PROCcleanup
         QUIT         QUIT
Line 50: Line 80:
         SYS `CoUninitialize`         SYS `CoUninitialize`
         ENDPROC         ENDPROC
-Should you wish to pause or stop playback prematurely you can do so using the following code segments:\\ \\ +</​code>​ 
 + 
 +Should you wish to pause or stop playback prematurely you can do so using the following code segments: 
 + 
 +<code bb4w> ​
         REM Pause playback:         REM Pause playback:
         SYS !(!m_mediaControl%+32),​ m_mediaControl% TO hr% : REM Pause()         SYS !(!m_mediaControl%+32),​ m_mediaControl% TO hr% : REM Pause()
Line 56: Line 90:
         REM Stop playback:         REM Stop playback:
         SYS !(!m_mediaControl%+36),​ m_mediaControl% TO hr% : REM Stop()         SYS !(!m_mediaControl%+36),​ m_mediaControl% TO hr% : REM Stop()
-Finally here are the functions **FNwide** and **FNguid** used by the above code:\\ \\ +</​code>​ 
 + 
 +Finally here are the functions **FNwide** and **FNguid** used by the above code: 
 + 
 +<code bb4w>
         DEF FNwide(A$)         DEF FNwide(A$)
         LOCAL M$         LOCAL M$
Line 69: Line 107:
         SYS `CLSIDFromString`,​ M%, C%         SYS `CLSIDFromString`,​ M%, C%
         = C%         = C%
 +</​code>​
 +
 ==== Fullscreen output ==== ==== Fullscreen output ====
-\\  ​To display a video file fullscreen, add the following code immediately before the call to **Run()**:\\ \\ + 
 +To display a video file fullscreen, add the following code immediately before the call to **Run()**: 
 + 
 +<code bb4w>
         REM Instantiate a video window object:         REM Instantiate a video window object:
         IID_IVideoWindow% = FNguid("​{56a868b4-0ad4-11ce-b03a-0020af0ba770}"​)         IID_IVideoWindow% = FNguid("​{56a868b4-0ad4-11ce-b03a-0020af0ba770}"​)
Line 95: Line 138:
         SYS IVideoWindow.put_FullScreenMode%,​ pVW%, TRUE TO hr%         SYS IVideoWindow.put_FullScreenMode%,​ pVW%, TRUE TO hr%
         IF hr% THEN ERROR 100, "Could not set fullscreen mode"         IF hr% THEN ERROR 100, "Could not set fullscreen mode"
-To close the fullscreen window, use the following code:\\ \\ +</​code>​ 
 + 
 +To close the fullscreen window, use the following code: 
 + 
 +<code bb4w>
         WM_CLOSE = &10         WM_CLOSE = &10
         SYS "​FindWindow",​ 0, "​ActiveMovie Window"​ TO hamw%         SYS "​FindWindow",​ 0, "​ActiveMovie Window"​ TO hamw%
         IF hamw% SYS "​SendMessage",​ hamw%, WM_CLOSE, 0, 0         IF hamw% SYS "​SendMessage",​ hamw%, WM_CLOSE, 0, 0
 +</​code>​
 +
 ==== Windowed output ==== ==== Windowed output ====
-\\  ​To display a video file in a window (whose size and position you can specify), add the following code immediately before the call to **Run()**:\\ \\ + 
 +To display a video file in a window (whose size and position you can specify), add the following code immediately before the call to **Run()**: 
 + 
 +<code bb4w>
         REM Instantiate a video window object:         REM Instantiate a video window object:
         IID_IVideoWindow% = FNguid("​{56a868b4-0ad4-11ce-b03a-0020af0ba770}"​)         IID_IVideoWindow% = FNguid("​{56a868b4-0ad4-11ce-b03a-0020af0ba770}"​)
Line 135: Line 187:
         SYS IVideoWindow.SetWindowPosition%,​ pVW%, left%, top%, right%, bottom% TO hr%         SYS IVideoWindow.SetWindowPosition%,​ pVW%, left%, top%, right%, bottom% TO hr%
         IF hr% THEN ERROR 100, "Could not set window rect"         IF hr% THEN ERROR 100, "Could not set window rect"
-To close the video window, use the following code:\\ \\ +</​code>​ 
 + 
 +To close the video window, use the following code: 
 + 
 +<code bb4w>
         WM_CLOSE = &10         WM_CLOSE = &10
         SYS "​FindWindow",​ 0, "​ActiveMovie Window"​ TO hamw%         SYS "​FindWindow",​ 0, "​ActiveMovie Window"​ TO hamw%
         IF hamw% SYS "​SendMessage",​ hamw%, WM_CLOSE, 0, 0         IF hamw% SYS "​SendMessage",​ hamw%, WM_CLOSE, 0, 0
 +</​code>​
playing_20a_20media_20file_20using_20direct_20show.txt · Last modified: 2018/04/15 13:03 by richardrussell