I have a collection of text files in my project containing level information that I want to load as streams and read in XNA. I am using MonoGame XNA and targeting Windows RT. Let's say I want to open /Content/Levels/Level1.txt as a stream. How would I do this?
On some other platforms using C# I would set the file's build action to resource and use
Application.GetResourceStream
but this is not available in XNA.
There are two kinds of storage in an XNA game: Title Storage and User Storage. See What is Storage? To read data from Title Storage, use TitleContainer.OpenStream as in this example.
string fileName = "Dummy.xml";
string resourceName = "Namespace0.Folder.Folder2.DataFolder." + fileName;
var resource = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName);
Related
I noticed that just about all audioplayers I can reach through code (XNA MediaPlayer and BackgroundAudioPlayer) need files at a special location - they just fail playing without any error message.
So I can copy the file to IsolatedStorage, now I need a normal path again (normal meaning one that fully qualifies it on the file system: an absolute path, so that I can use System.IO.File on it).
Is that possible, and if yes, how?
(I would like to give that path then to a Microsoft.Xna.Framework.Media.MediaPlayer, hoping that it can play from that location, since it seems not to be able to play from arbitrary locations.)
Have you looked at MediaElement? (System.Windows.Controls.MediaElement) You can set the source of the control with an IsolatedStorageFileStream:
using (var isoStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
if (isoStorage.FileExists(strFilename))
{
IsolatedStorageFileStream isoAudioFile = IsolatedStorageFileStream(strFilename, FileMode.Open, FileAccess.Read, isoStorage);
medAudioPlayer.SetSource(isoAudioFile);
}
}
Where medAudioPlayer is your MediaElement.
Note: this is for Windows Phone 8.1 Silverlight apps. Not sure if it's available in Universal apps.
I require to include a video file for playback in xap file, instead of separately uploading it in Isolated Storage.
What are my options?
Originally I had wanted to play a video file from the MediaLibrary.
Video playback of a file stored in Media Library
As I learnt, it is not possible to do so. Hence, I am exploring the option of at least including the video file inside xap file.
Kindly note that the API for video playback supports reading video files only from Isolated storage, hence I can't just include it in the project and expect it to work.
Assuming your video is located inside assets folder (in your .xap file) the following should work:
private void PlayVideo()
{
var mediaPlayerLauncher = new MediaPlayerLauncher
{
Media = new Uri("Assets/video.mp4", UriKind.Relative),
Location = MediaLocationType.Install,
Controls = MediaPlaybackControls.Pause | MediaPlaybackControls.Stop,
Orientation = MediaPlayerOrientation.Landscape
};
mediaPlayerLauncher.Show();
}
Add it as a resource as you add images to your project. Solution explorer.
I just started on my second Windows Phone application, and I ran into a problem (ehm..challange). In my app, I have added a folder called "Images", and some sub-folders, like this:
Images -> boys -> graphs
The boys folder contains 1 xml file, and the graphs folder contains hundreds of .gif images. And I'm now wondering how to access these files, how can I build them into the .xap file, what's the recommended way to go?
Should I set the files to "Content" or "Resource", "Copy to output folder"?
And how do I refer to these files, both the xml file in "boys", and the gif images in "graphs"?
A bit confused, and hoping that there is someone who can kick me in the right direction :)
edit, more info
I got it working, loading the xml file with the code below, I haven't tried with the images yet, but is this "the way to do it"?
string xmlBoys = #"images/boys/Names.xml";
Uri uri = new Uri(xmlBoys, UriKind.Relative);
StreamResourceInfo sm = Application.GetResourceStream(uri);
System.Xml.XmlReader xr = System.Xml.XmlReader.Create(sm.Stream);
XDocument data = XDocument.Load(xr);
If you set the BuildAction on the images to Content you can refer to them by the relative path.
e.g.: new Uri("\Images\boys\graphs\img1.gif", UriKind.Relative);
You don't need to "Copy to output folder" unless you need them there for your own purposes. You probably don't. That option is an artefact of other types of project. Everythign you need to distribute will be bundled in the XAP.
Importantly, however, note that WP7 does not have native support for gif format files. I'd suggest converting these to PNG before trying to use them.
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.
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.
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
}
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.
I'm doing a sample which will run mp3 files which are selected by the user. I
want to calculate the playing time of the file (e.g. 00:05:32). How can I calculate the playing time?
You could use TagLib Sharp
It exposes TagLib.AudioProperties.Duration
For Alvas.Audio library see code below
using (Mp3Reader mr = new Mp3Reader(File.OpenRead("len.mp3")))
{
int durationMS = mr.GetDurationInMS();
TimeSpan durationTS = TimeSpan.FromMilliseconds(durationMS);
}
You suggest in the tag that you're doing this in C#. This question deals with it:
Finding MP3 length in C#
And there's some code for reading the MP3 header and extracting relevant information (like the length) here:
http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=79
I believe the Windows Media API (or windows mixer api or something, I can't recall the exact name) has a way to open and read sound files like mp3 and maybe get the time from it too. As an added bonus, by using that API you can open any audio format that will work in say Windows Media Player, so you're not limited to just mp3's.