10

EDIT: I changed my question to better clarify the issue. How is it possible to play a video from a byte array (taken from embedded resource) using DirectShow.Net library?

Since I'm going to prevent users from accessing the video file, I need to embed the video file as resource and play it.

Thanks in advance.

Harry.B
  • 621
  • 5
  • 18
  • Resources can easily extracted from .Net assemblies. You can encrypt the data, but the key has to be in your code, and again the sourcecode can be easily extracted from your .Net assembly. – habakuk Jul 12 '11 at 13:49
  • I'm going to use protectors such as SmartAssembly. – Harry.B Jul 12 '11 at 14:15

3 Answers3

4

It's a bit non-standard, but you could use something like WCF to self-host an endpoint inside your desktop application. Then set the source of the video input to be the "URL" to your self-hosted endpoint. That would work for WPF or WinForms. Not sure about Silverlight though.

The self-hosted endpoint could pull the media from your embedded resources and stream it from there.

NathanAW
  • 3,329
  • 18
  • 19
  • Thanks, that's a very cool idea. Is it possible to use WCF RIA Services to interact between Silverlight application and Windows application? – Harry.B Jul 05 '11 at 18:35
  • 1
    I don't know for sure. Can you describe this a bit more? You want to have a desktop app host the WCF RIA service and then a silverlight app running on the client too? In theory, I think this would work, but it's definitely a non-standard use-case. You might have some issues with cross domain stuff too. – NathanAW Jul 05 '11 at 18:45
  • As I mentioned, I'm goinig to play a video resource as stream. Since I did not find an easy solution, I thought it might be practical to use silverlight MediaElement control in windows application, because MediaElement accepts media source of type Stream. – Harry.B Jul 06 '11 at 18:11
  • 1
    I see. I don't know that you'll be able to directly host the silverlight control in a WPF app, though I suppose that you could host the silverlight control in an embedded browser control. Then that could point back to the WPF app's self-hosted WCF service. If it's an option, WPF has it's own media control that could play the contents for you. It's slightly different than the WPF control (I think SL version is better), but the WPF control might do the trick for you and eliminate the need for the SL control. – NathanAW Jul 06 '11 at 18:30
  • Thanks, but WPF media control does not accept FileStream as media source. Do you know any way of playing an embedded video resource with WPF without needing to write the contents to a temporary file? Silverlight version accepts input parameter of type Stream(i.e. FileStream, MemoryStream,...) – Alireza Maddah Jul 06 '11 at 20:45
  • The WPF media element has a Source property, accepting a URI to the resource. This can be a local file, or it can be a remote resource (like http:// myserver.com/file.wmv). If you were to self-host a WCF service inside the WPF application, then you could point the WPF media element to a URI that looked like http:// localhost:5555/videos.svc. This service could then serve the video back to the WPF media element, which would treat it like a remote resource somewhere else on the internet. – NathanAW Jul 06 '11 at 21:00
3

It sounds to me like the problem is not so much how to use the DirectShow library (the `DirectShow.Net Forum is specifically designed for that), but rather how to use an embedded resource.

I ran into something similar a few years back on a contract job where an employer was worried that some customer might steal his proprietary information. My information was in hundreds of PDF documents, but the idea works the same for video files.

Here's how I tackled the problem:

  • First, place the video file in your list of resources: I use Visual Studio, so I go to the Project's Properties, click the Resources tab, select the Files option, then select Add Resource > Add Existing File...

  • Add the following two namespaces to the code file you will be using:

using System.IO;
using System.Diagnostics;
  • Finally, where you want to play your video file, just do something similar to the following:
 Process player = null;
 string tempFile = "~clip000.dat";
 try {
   File.WriteAllBytes(tempFile, Properties.Resources.MyMovie_AVI);
   player = Process.Start(tempFile);
   player.WaitForExit();
 } finally {
   File.Delete(tempFile);
 }

Most likely, you will not be calling the Process.Start method, but rather the appropriate DirectShow method. The idea is still the same: Extract your resources as a byte array, write them to a new, temporary file, use the file, then delete that file whenever you are done.

Be sure to put the Delete statement in the finally block so that if any errors occur or your user closes the program while the file is still playing, your application still cleans up the old file.

EDIT:

I think this might be a viable way of doing this:

using (MemoryStream ms = new MemoryStream(Properties.Resources.MyMovie_AVI)) {
  // Now you have to find a way in `DirectShow` to use a Stream
}
  • Thanks, but That's not a secure solution. The user can still copy the video file from temp directory. I want to do the job without needing to write the resource contents to the hard disk. – Harry.B Jul 09 '11 at 15:41
  • See Edit above. I added a `MemoryStream` option. Does `DirectShow` have anything that takes a stream? –  Jul 11 '11 at 15:05
  • Thanks, I know how to use MemoryStream to read the video file from embedded resource, The problem is "How to play a video from byte array?". – Harry.B Jul 12 '11 at 07:17
1

Can you use a different library?

I used the WPF MediaKit to do some non-standard streaming of a secure, live h264 video stream. The developer (Jermiah Morill) was very responsive, and the customization I could perform was extensive (since you get the source).

At that point, you could embed the video as an embedded resource, load the byte array (perhaps either part of it at a time or the entire file) into memory, and play from memory.

Jason
  • 4,897
  • 2
  • 33
  • 40
  • You bet. It's been a while, but I don't believe it includes any other codecs; it uses the ones already installed on the system. – Jason Jul 12 '11 at 14:11