I've got a project in VS2003 where I've added a number of images and a video clip as an embedded resource on 'Build Action'. I can access the images easy enough by using the following code:
System.Drawing.Bitmap bitmap =
new System.Drawing.Bitmap(GetType(), "sampleImage.jpg"); this.pictureBox1.Image = bitmap;The problem is accessing the embedded .AVI; both the ActiveX Windows Media Player and the DirectX AudioVideoPlayback require a string pointing to a file
Accessing Video File Thru ActiveX Windows Media Player Control:
private
AxWMPLib.AxWindowsMediaPlayer axWindowsMediaPlayer1;this
.axWindowsMediaPlayer1.URL = "sampleVideo.avi";Accessing Video File Thru DirectX 9:
using
Microsoft.DirectX.AudioVideoPlayback; Video vid = new Video("sampleVideo.avi", false);Any help would be greatly appreciated.

Accessing .AVI As Embedded Resource
Arvind Agarwal - Skelta
The best workaround that I can think of is to simply deserialize the video into a separate avi file that you then pass to WMP. Or if that is not acceptable, you could create a custom ActiveX control using DirectShow that could accept input directly from the resource, deserialize it if necessary, and then play it.
Michael Blome Visual C# Documentation Team
Mr Pro Tools
How about this...
DirectShow and Windows Media Player allow a URL instead of a filename to play a video. You could create a thread in your app that listens on a dynamic socket for HTTP requests on the loopback adapter (127.0.0.1) and only takes requests from your app (look in the header or put something in the url that identifies the request). Then you could read the resource into memory and feed it back through the web request.
Bill
Bo Persson
{
/// <summary>
/// how to grab resources, look them up and use them to pull out embedded icons or.......
/// </summary>
public class Resource_Graber
{
static System.Collections.ArrayList theResources;
/// <summary>
/// this gets a list of resources, this will make it ez to know what to pass grabStram
/// </summary>
/// <returns>the strings of resources</returns>
public static string [] getResourceList()
{
if(theResources == null)
theResources = new System.Collections.ArrayList();
string[] names = System.Reflection.Assembly.GetAssembly((new Resource_Graber()).GetType()).GetManifestResourceNames();
foreach (string s in names)
{
theResources.Add(s);
}
// ok y (new Resource_Graber()).GetType()
// well it can be all most anything!!! from your namespace
return names;
}
/// <summary>
/// this will return a stream, send it into a new System.Drawing.Icon(X) or something
/// this can even just be a unique part of the string like myIcon.ico
/// </summary>
/// <param name="nameToGrab">string of stream to grab</param>
/// <returns>the stream</returns>
public static System.IO.Stream grabStream(string nameToGrab)
{
if(theResources == null)
getResourceList();
System.Reflection.Assembly A = System.Reflection.Assembly.GetExecutingAssembly();
foreach (string aResource in theResources)
{
if(aResource.IndexOf(nameToGrab) != -1)
{
return A.GetManifestResourceStream(aResource);
}
}
return null;
}
#region example
/// <summary>
/// an example of using the embedded icon
/// </summary>
/// <returns>a icon</returns>
public static System.Drawing.Icon icon()
{
System.Drawing.Icon ico = new System.Drawing.Icon( Noj.Tools.Resource_Graber.grabStream(
// change this
"ColorOverlay.Noj.Tools.Reminder.Reminder.ico"
// <-
));
return ico;
}
/// <summary>
/// make dynamic icon from text
/// </summary>
/// <returns>a icon</returns>
// for use below
[System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint="DestroyIcon")]
static extern bool DestroyIcon(System.IntPtr hIcon);
public static System.Drawing.Icon makeIcon()
{
// Create a graphics instance that draws to a bitmap
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(16, 16);
System.Drawing.SolidBrush brush = new System.Drawing.SolidBrush(System.Drawing.Color.DarkRed);
System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(bitmap);
// Draw the temperature and the degrees symbol to the bitmap using the user selected font
string temperatureOnlyStr = "Sex";
System.Drawing.Font f = new System.Drawing.Font("Lucida Sans Typewriter", 5F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
graphics.DrawString(temperatureOnlyStr, f, brush, 0, 0);
// Convert the bitmap into an icon and use it for the system tray icon
System.IntPtr hIcon = bitmap.GetHicon();
System.Drawing.Icon icon = System.Drawing.Icon.FromHandle(hIcon);
// unfortunately, GetHicon creates an unmanaged handle which must be manually destroyed
DestroyIcon(hIcon);
return icon;
}
#endregion ---example---
}
}
my email: jon.use@charter.net
let me know if it helped
daxwhit
This is an interesting problem, which is not always the kind of problem one would prefer to have. ;-) However I think it is solvable without too much headache.
If the video will always be in AVI format and always small enough to fit on the clipboard all at once, then I would first investigate the possibility of using Video For Windows instead of DirecdtShow. VfW has the GetAVIFromClipboard http://msdn.microsoft.com/library/default.asp url=/library/en-us/multimed/htm/_win32_avigetfromclipboard.asp function and you could just make VfW calls using P/Invoke. But VfW is very old technology and one potential issue is whether it be supported on Vista. It's also much less efficient than DShow in terms of memory usage and performance.
If VfW doesn't appeal to you, then you will need to create a custom DirectShow "source filter". This is fairly straightforward and there are some good samples out there--in fact there is probably a sample in the SDK for an "in-memory source filter" which you might be able to use out of the box without any need for modification. A source filter is a COM object that will accept blocks of data in real time as you marshall them across from your C# app and then passes them, using a well-defined protocol, to the DShow AVI parsers, which pass the data to the decoders, renderers etc. See the DirectShow docs on MSDN for more info. I know that many people have used DShow from C# successfully so it can be done. You can ask questions on the DirectShow discussion forum at: http://DISCUSS.MICROSOFT.COM/archives/DIRECTXAV.html or the foum at http://forums.microsoft.com/msdn/showforum.aspx forumid=129&siteid=1 .
Good luck!
Roger Rombooth
Hi, I've been doing a little research and I came across an article in another forum that demonstrated viewing a file using DirectShow and the Interop.QuartzTypeLib which I've added as a reference to the project. I am able to play the file but I don't know if I'm going in the right direction to access this same media as an embedded resource Any help would be greatly appreciated.
Code Snippet ==============================================
using
System;using
System.Drawing;using
System.Collections;using
System.ComponentModel;using
System.Windows.Forms;using
System.Data;using
QuartzTypeLib;namespace
VideoDirectShow{
/// <summary> /// Summary description for Form1. /// </summary> public class Form1 : System.Windows.Forms.Form{
private System.Windows.Forms.Panel panel1; /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.Container components = null; private const int WM_APP = 0x8000; private const int WM_GRAPHNOTIFY = WM_APP + 1; private const int EC_COMPLETE = 0x01; private const int WS_CHILD = 0x40000000; private const int WS_CLIPCHILDREN = 0x2000000; private FilgraphManager m_objFilterGraph = null; private IBasicAudio m_objBasicAudio = null; private IVideoWindow m_objVideoWindow = null; private IMediaEvent m_objMediaEvent = null; private IMediaEventEx m_objMediaEventEx = null; private IMediaPosition m_objMediaPosition = null; private IMediaControl m_objMediaControl = null; public Form1(){
// // Required for Windows Form Designer support //InitializeComponent();
// // TODO: Add any constructor code after InitializeComponent call //m_objFilterGraph =
new FilgraphManager();m_objFilterGraph.RenderFile("Sample.avi");
m_objBasicAudio = m_objFilterGraph
as IBasicAudio; try{
m_objVideoWindow = m_objFilterGraph
as IVideoWindow;m_objVideoWindow.Owner = (
int) panel1.Handle;m_objVideoWindow.WindowStyle = WS_CHILD | WS_CLIPCHILDREN;
m_objVideoWindow.SetWindowPosition(panel1.ClientRectangle.Left,
panel1.ClientRectangle.Top,
panel1.ClientRectangle.Width,
panel1.ClientRectangle.Height);
}
catch (Exception){
m_objVideoWindow =
null;}
m_objMediaEvent = m_objFilterGraph
as IMediaEvent;m_objMediaEventEx = m_objFilterGraph
as IMediaEventEx;m_objMediaEventEx.SetNotifyWindow((
int) this.Handle,WM_GRAPHNOTIFY, 0);m_objMediaPosition = m_objFilterGraph
as IMediaPosition;m_objMediaControl = m_objFilterGraph
as IMediaControl;m_objMediaControl.Run();
}
vbrada
me_someone
Alan Brewer
Rich:
You might be able to use this code later, but what you have created is basically a Media Player with the same problem--e.g. it only knows how to read certain kinds of files from disk. Once you have created your custom source filter, you might be able to use the code above to specify an .resx file and then auto-magically choose your filter to read the bytes. It's all in the DShow docs, also Pesce's book on DirectShow is good for what you are trying to do.