[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
May 29th, 2009 at 2:59 am
[…] [Windows Mobile] How to play audio/video C# or DirectShow.NET CF Part I […]
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 […]
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 3rd, 2009 at 2:30 pm
Try to run it on real device it wont work on Emulator
June 18th, 2009 at 11:22 am
I couldn’t get the app to work. It’s not playing the video files.
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 21st, 2009 at 12:48 am
Windows mobile version :Windows 6.1
File type:MPEG
June 21st, 2009 at 1:38 am
Have you tried example from DirectShowNETCF?
if it fails probably you dont have mpeg decoder
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.
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 18th, 2009 at 10:02 am
I used the ILDASM to diassemble it and used ILASM to assemble back again with a strong key file and I am getting this error message.
System.MissingMethodException was unhandled
Message: File or assembly name ‘Interop.QuartzTypeLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=F47E5832F45865E5′, or one of its dependencies, was not found.
Can you please help?
October 20th, 2009 at 10:48 pm
Tried to deploy on wm5 smartphone emulator, got error “can’t find Pinvooke DLL DirectShowNetCF.Native.dll
October 20th, 2009 at 11:16 pm
DirectShowNetCF.Native.dll you should put on device/emulator by yourself
December 16th, 2009 at 6:24 am
I can play movie clip on my Omnia(i8000)
but i got error when i want to play third movie clip.
first and second movie clip is ok. but when i load the third like this:
player.renderFile(filename);
It returns FALSE.
December 16th, 2009 at 8:38 am
false means that its impossible to render clip for some reasons for example there not required codec exist
April 16th, 2010 at 9:38 pm
This code works when the file is local. if one is to point to a URL, the code doesn’t work. say the file resides at http://www.abc.com/video1.3gp. It doesn’t have the capability of stream. What’s the solution to this?
April 19th, 2010 at 11:43 am
solution? hm…
implement your own push source that will also contain 3gp splitter
April 25th, 2010 at 1:28 am
When I play the video in normal mode, it always plays 90 degree rotated. But when i play in in fullscreen, it plays perfect. Can you please suggest me how to avoid the 90 degree rotation.
April 26th, 2010 at 10:05 pm
Any suggestions please? Can the rotation be avoided using code or is it something hardware dependent?
April 26th, 2010 at 10:12 pm
As option you can implement transform filter that will rotate preview