[Windows Mobile] How to play audio/video C# or DirectShow.NET CF Part I
“DirectShow is a multimedia framework and API produced by Microsoft for software developers to perform various operations with media files or streams.” (c) Wikipedia
I`m not sure what earliest version of Windows Mobile that supports DirectShow, but i`m totally sure that Windows Mobile 5.0 and higher definitly suppor DirectShow.
So if you developing you application on C++ you have all headers and libs and it aint problem to use DirectShow, but if you developing on C# then welcome thats article exactly for you
So to make work we need to import required Interfaces and as DirectShow based on COM technologies we need to import CoCreateInstance function
[DllImport("ole32.dll")]
public static extern int CoCreateInstance(
[In] ref Guid rclsid,
[In] IntPtr pUnkOuter,
[In] uint dwClsContext,
[In] ref Guid riid,
[Out, MarshalAs(UnmanagedType.Interface)] out object pv);
In this post i will explain how to play video or audio files. So to play media files we need 2 interfaces:
IGraphBuilder and IMediaControl
to play any media file (if codecs and required filters installed) it will be enough to call method RenderFile of IGraphBuilder interface and method Run of IMediaControl interface… thats easy, isnt it?
[ComVisible(true), ComImport,
Guid("56A868A9-0AD4-11ce-B03A-0020AF0BA770"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IGraphBuilder
{
[PreserveSig]
int AddFilter(
[In] IntPtr pFilter,
[In, MarshalAs(UnmanagedType.LPWStr)] string pName);
[PreserveSig]
int RemoveFilter([In, MarshalAs(UnmanagedType.Interface)] object pFilter);
[PreserveSig]
int EnumFilters([Out, MarshalAs(UnmanagedType.Interface)] out object ppEnum);
[PreserveSig]
int FindFilterByName(
[In, MarshalAs(UnmanagedType.LPWStr)] string pName,
[Out, MarshalAs(UnmanagedType.Interface)] out object ppFilter);
[PreserveSig]
int ConnectDirect(
[In, MarshalAs(UnmanagedType.Interface)] object ppinOut,
[In, MarshalAs(UnmanagedType.Interface)] object ppinIn,
[In, MarshalAs(UnmanagedType.LPStruct)] IntPtr pmt);
[PreserveSig]
int Reconnect([In, MarshalAs(UnmanagedType.Interface)] object ppin);
[PreserveSig]
int Disconnect([In, MarshalAs(UnmanagedType.Interface)] object ppin);
[PreserveSig]
int SetDefaultSyncSource();
[PreserveSig]
int Connect(
[In, MarshalAs(UnmanagedType.Interface)] object ppinOut,
[In, MarshalAs(UnmanagedType.Interface)] object ppinIn);
[PreserveSig]
int Render([In, MarshalAs(UnmanagedType.Interface)] object ppinOut);
[PreserveSig]
int RenderFile(
[In, MarshalAs(UnmanagedType.LPWStr)] string lpcwstrFile,
[In, MarshalAs(UnmanagedType.LPWStr)] string lpcwstrPlayList);
[PreserveSig]
int AddSourceFilter(
[In, MarshalAs(UnmanagedType.LPWStr)] string lpcwstrFileName,
[In, MarshalAs(UnmanagedType.LPWStr)] string lpcwstrFilterName,
[Out] out IntPtr ppFilter);
[PreserveSig]
int SetLogFile(IntPtr hFile);
[PreserveSig]
int Abort();
[PreserveSig]
int ShouldOperationContinue();
}
[ComVisible(true), ComImport,
Guid("56A868B1-0AD4-11CE-B03A-0020AF0BA770"),
InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IMediaControl
{
[PreserveSig]
int Run();
[PreserveSig]
int Pause();
[PreserveSig]
int Stop();
[PreserveSig]
int GetState(
int msTimeout,
out int pfs);
[PreserveSig]
int RenderFile(string strFilename);
[PreserveSig]
int AddSourceFilter(
[In] string strFilename,
[Out, MarshalAs(UnmanagedType.IDispatch)] out object ppUnk);
[PreserveSig]
int get_FilterCollection(
[Out, MarshalAs(UnmanagedType.IDispatch)] out object ppUnk);
[PreserveSig]
int get_RegFilterCollection(
[Out, MarshalAs(UnmanagedType.IDispatch)] out object ppUnk);
[PreserveSig]
int StopWhenReady();
}
To make life more easier i created class CFilterGraph (simplified version of TFilterGraph from DSPack that in Delphi) so here is class that exports 4 methods:
renderFile, play, stop and pause.
using System;
namespace DirectShowNETCF
{
public class CFilterGraph: IDisposable
{
private IGraphBuilder graph = null;
private IMediaControl control = null;
public CFilterGraph()
{
object obj = null;
Guid clsid = CLSID_.FilterGraph;
Guid riid = IID_.IFilterGraph2;
PInvoke.CoCreateInstance(ref clsid, IntPtr.Zero, (uint)CLSCTX_.INPROC_SERVER, ref riid, out obj);
graph = (IGraphBuilder)obj;
control = (IMediaControl)graph;
obj = null;
}
public void Dispose()
{
stop();
System.Runtime.InteropServices.Marshal.ReleaseComObject(graph);
graph = null;
control = null;
}
public bool renderFile(string fileName)
{
return ((graph != null) && (graph.RenderFile(fileName, null) >= 0));
}
public bool play()
{
return ((control != null) && (control.Run() >= 0));
}
public bool stop()
{
return ((control != null) && (control.Stop() >= 0));
}
public bool pause()
{
return ((control != null) && (control.Pause() >= 0));
}
}
}
Thats all
enjoy and have fun, to play mediafiles use Player class from DirectShowNETCF
Filed under: Programming
July 11th, 2009 at 10:33 am
All sources of player class you can find in this post its not a problem to copy it and build library named “QuartzTypeLib”
P.S. i wont provide sources of library for free (I`ve already found 2 guys that took my first sources and now saying that it was made by themself…)
July 11th, 2009 at 9:44 am
I got it to work using .3gp files. I tried using it an application that as a signed assembly (strong name). The compilation failed because ‘Interop.QuartzTypeLib’ does not have a strong name. Could you please create a strong name for it. Or is there a place where I can download it ,to create the strong name myself?
Thanks.
June 21st, 2009 at 1:38 am
Have you tried example from DirectShowNETCF?
if it fails probably you dont have mpeg decoder
June 21st, 2009 at 12:48 am
Windows mobile version :Windows 6.1
File type:MPEG
June 18th, 2009 at 11:51 am
Windows mobile version?
File type? Encoder name?
P.S. you should try Player class
from http://alexmogurenko.com/blog/directshownetcf/
June 18th, 2009 at 11:22 am
I couldn’t get the app to work. It’s not playing the video files.
June 3rd, 2009 at 2:30 pm
Try to run it on real device it wont work on Emulator
June 3rd, 2009 at 8:39 am
Man I’m trying to run your code on Emulator trying with .mp3, .wmv and .mp4 files but it does not show up anything besides that control.Run() Method does not do anything ahead besides Returning back to callee… Please Can you help me with this >>>
June 1st, 2009 at 6:57 pm
[…] previous post i explained how to play video or audio on Windows Mobile devices using DirectShow. I`ve received […]
May 29th, 2009 at 2:59 am
[…] [Windows Mobile] How to play audio/video C# or DirectShow.NET CF Part I […]