i'm building a wp7 application for a game using silverlight & XNA
i have an mp3 file called "Punch1.mp3" (Build action : resource ) stored inside a folder called "SoundEffects" inside the project folder
and i want to play the file using this code
StreamResourceInfo info;
Uri myuri = new Uri("/SoundEffects/Punch1.mp3", UriKind.Relative);
info = App.GetResourceStream (myuri);
punch1 = SoundEffect.FromStream(info.Stream ) ;
punch is defined in the code here :
public static SoundEffect punch1;
the problem is that it raises a nullreference exception in the third line claiming that info is null
and that's true in the debugging mode , i found that the resource stream info is null
i think this is because the it can't read the file although the uri is correct
You can try two things
- Clean and rebuild the project
- Try appending project name in URI "/PhoneApp1;component/SoundEffects/Punch.mp3"
Since you're using the XNA assembly anyway, you can use TitleContainer.OpenStream instead (with a relative URI) and have the audio file build set as Content.
I agree with Haris Haqsan that your URI string is bad.
Uri myuri = new Uri("/PhoneBoxing;component/SoundEffects/Punch1.mp3", UriKind.Relative);
But you should also consider switching to using content files instead embedding them at resources as it can help your application start up time. Depending on the amount of files we are talking about, it can make a big difference.
Set your Build Action to content and your code should look like:
FileStream stream = new FileStream("/SoundEffects/Punch1.mp3", FileMode.Open, FileAccess.Read);
in the following code :
Uri myuri = new Uri("/SoundEffects/Punch1.mp3", UriKind.Relative);
info = App.GetResourceStream (myuri);
punch1 = SoundEffect.FromStream(info.Stream ) ;
SoundEffect.FromStream() expects a wave file stream not an MP3 as shown here : http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.audio.soundeffect.fromstream.aspx .
so solution to find a mp3 > wav convertor or just find another way to load mp3 to WP7
considering the picture this is normal URI in normal cases can't evaluate expression of isfile .
I was experiencing the same issue on my machine, the InvalidOperationException is a little confusing. All I had to do was re-encode the wav file to the specifications listed on MSDN.
After I did that, it worked perfectly.
Related
I am just learning c# and have been struggling to work with URIs in WPF. I've googled around a fair bit but not having much luck.
Essentially I'm trying to have a BitmapImage object stored as a property in a Car object. I then want to display the BitmapImage in an Image control on a WPF form.
The app is a simple app (it's for a Uni assignment), so no database, etc.
I have two methods of doing this. The first is that I'm preloading Car data from a text file, including the filename of the JPG I want to load. I have included the JPG in a directory called Files which is off the main directory where my source code and class files are. I have set the JPG file to 'Content' and 'Always copy'. When I run a Debug, it copies the Files directory and the JPG to the debug\bin directory.
My code creates a BitmapImage by referring to the JPG using a URI as follows;
BitmapImage myImage = new BitmapImage (new Uri("Files/" + Car.Imagefilename, UriKind.Relative);
Car.Image = myImage;
ImageControl.Source = myImage;
If I step through this code in the debugger, it sometimes works and displays the image, but most of the time it doesn't.
My second method is when a user creates a new Car. This method always works. In this one, I use a file dialog box (dlg) to select the image and use an absolute path.
BitmapImage myImage = new BitmapImage (new Uri(dlg.Filename, UriKind.Absolute);
Car.Image = myImage;
ImageControl.Source = myImage;
So....I can't work out why the first method doesn't work. I think it's got something to do with the relative reference, but I can't work out how to syntax that properly to work. I've tried using "pack:,,,", I've tried adding "component", I've tried an '#' before the "pack". I can't seem to find something that explains this simply.
Apologies if this is straight forward but it's doing my head in! Appreciate any pointers.
If the image files are located in a "Files" folder of your Visual Studio project, you should set their Build Action to Resource (and Copy to Output Directory to Do not copy), and load them by a Resource File Pack URI:
var image = new BitmapImage(new Uri("pack://application:,,,/Files/" + Car.Imagefilename));
Car.Image = image;
ImageControl.Source = image;
There is no need to copy the files anywhere. Images are loaded directly from the assembly.
First try to load the image file using its absolute path. For example if the images are stored in c:\projects\yourproject\files, then try using something like
BitmapImage myImage = new BitmapImage (new Uri("c:/projects/yourproject/files/carname.jpg", UriKind.Absolute);
If it works, what you are facing is an path calculation issue.
At this point you may either calculate the Absolute with reference to your executable using AppDomain.CurrentDomain.BaseDirectory at runtime or use App.Config to store the path and reference it from there.
Cheers
I want to convert ogg file to wav and then play it on wp8 devives.
I've already checked many solutions but none of them worked. This looks promising but something doesn't work:
string _audioPath = "/SomeProject;component/Sounds/a_dog.ogg";
var stream = Application.GetResourceStream(new Uri(_audioPath, UriKind.Relative)).Stream;
using (var vorbis = new NVorbis.VorbisReader(stream, true))
{
float[] buf = new float[vorbis.TotalSamples];
vorbis.ReadSamples(buf, 0, (int)vorbis.TotalSamples);
}
When I execute it I see FileNotFoundException at VorbisReader contruction. I also checked if stream is readable and it is. I was able to get the file content using Read method.
Do you have any ideas why it doesn't work? Maybe you know some other library for wp8 which can decode ogg files?
[EDIT] I downloaded source code of NVorbis and used it directly from my project, and when i do this I don't get any FileNotFoundExceptions and everything seems to work. Maybe this exception is caused by missing library? I've got NVorbis reference added...
I think you are running into the same issue as this guy. Short version: I believe your Pack URI should be "pack://application:,,,/SomeProject;Component/Sounds/a_dog.ogg". NVorbis is not actually throwing the exception itself, but is instead causing the resource stream to do so...
Is there any way to determine if WPF will be able to load an image file without attempting to construct a BitmapImage and catching the exception if it fails?
I'm creating an image browser that attempts to show previews of all the images on a removable drive. There could be a lot of files that aren't images and catching an exception for each one seems somewhat inefficient but I can't think of a way that isn't prone to error.
Any suggestions?
Thanks,
Mark
I recently asked a very similar question and got an excellent answer here.
Basically, you find all the codecs on a user's machine which BitmapImage can use to open various image formats. From these codecs, you build a list of the file extensions that these can open.
Then, when your program tries to open a file, check the extension of that file against this list.
WPF uses WIC to handle images. It contains a core set of codecs that handle common image formats, and I believe you can hard-code the extensions of these from here. WIC is also extensible, so, for example, camera manufacturers can incorporate custom image formats into WIC. The code in the answer above searches your computer for these extra codecs, and provides the corresponding file extensions for these.
This method assumes that the file extensions are correct for a file. This is usually a fair assumption in most cases though - even Windows Explorer is happy to assume this. Still, I would wrap the BitmapImage construction in a try-catch, should the odd rogue file appear where the extension appears to be an image, but it still won't open.
EDIT: I have also wrapped this functionality into a class you can copy-paste into your own project here.
WPF uses WIC, what you want is demonstrated in C++ in the MSDN but the decompiled sources of the framework show that IWICImagingFactory::CreateComponentEnumerator isn't even exposed in the internal class of the framework.
Your best solution would be to create a static list of extensions supported (The formats that WIC support out-of-the box are on MSDN) and use it.
First, you can try to check the image file extension to verify if your application is able to read it.
Then you have to read Validate image from file in C#
and here Getting image dimensions without reading the entire file
I found the answer to this in another question on StackOverflow, but I don't remember the question I got it from. In any event, here's some code I wrote based on what one of the answerws to that question said:
public static string GetImageFileExtension( byte[] plateImage ) {
string imageFileExtension = String.Empty;
using ( Stream ms = new MemoryStream( plateImage ) ) {
BitmapDecoder decoder = BitmapDecoder.Create( ms, BitmapCreateOptions.None, BitmapCacheOption.None );
if ( decoder is BmpBitmapDecoder ) imageFileExtension = ".bmp";
else if ( decoder is GifBitmapDecoder ) imageFileExtension = ".gif";
else if ( decoder is IconBitmapDecoder ) imageFileExtension = ".ico";
else if ( decoder is JpegBitmapDecoder ) imageFileExtension = ".jpg";
else if ( decoder is PngBitmapDecoder ) imageFileExtension = ".png";
else if ( decoder is TiffBitmapDecoder ) imageFileExtension = ".tiff";
else if ( decoder is WmpBitmapDecoder ) imageFileExtension = ".wmp";
}
return imageFileExtension;
}
This works well in production code.
Here is the task-related part of the VS2010 project (Windows Phone) structure:
The code is being executed from DummyMediaLibProvider.cs:
public class DummyMediaLibProvider: IMediaLibProvider
{
...
StreamResourceInfo albumArtPlaceholder =
Application.GetResourceStream(
new Uri("../Images/artwork.placeholder.png", UriKind.Relative));
artwork.placeholder.png Build Action is set to Content.
Still, whenever I run the code, Application.GetResourceStream returns null.
What may be the reason for the resource not being read to memory?
I have attempted to delete obj directory of the project, did Clean and Rebuild, but so far nothing helped.
Update:
If I apply Build Action: Resource to artwork.placeholder.png, I can get the resource stream ok though.
P.S. This is not the duplicate of Application.GetContentStream returns null for content Uri since the last had the extension (particurarly .xml) related problem.
The path supplied Application.GetResourceStream isn't relative to the position of the class, but relative to the application package.
StreamResourceInfo albumArtPlaceholder =
Application.GetResourceStream(
new Uri("Images/artwork.placeholder.png", UriKind.Relative));
Would be the correct path. You can also try with a full pack URI. (see MSDN)
And finally, Resource would be the correct Build Action for this.
Here's the code snippet
String str= ??????? // I want to assign c:/my/test.html to this string
Uri uri= new Uri (str);
Stream src = Application.GetContentStream(uri).Stream;
What's the correct way to do this? I'm getting "URI not relative" Exception thrown
Your problem is specific to WPF. See the Application.GetContentStream method.
You'll read that this method requires a relative URI. See "WPF Application, Resource, Content and Data files".
You have a file path - if you want to make it a URI add "file:///", ie. "file:///c:/my/test.html"
For local file URIs, you need to prefix it with:
file:///
I think you'll find your problem is that Application.GetContentStream is for a resource stream for a content data file that is located at the specified Uri. That is, deployed alongside an executable assembly.
If you look at: http://msdn.microsoft.com/en-us/library/aa970494(VS.90).aspx#Site_of_Origin_Files
You should find that the file:/// syntax as stated above is correct... But if you're going to open them you'll probably want some kind of switch to work out how to get the stream:
FileInfo fileToSave;
if (!existingFile.IsFile)
throw new ArgumentException("Input URI must represent a local file path", "existingFile");
fileToSave = new FileInfo(existingFile.LocalPath);
return fileToSave.Open(/* Args based on your needs */)
And similarly if it's a web URI:
if (!existingFile.Scheme.StartsWith("http"))
throw new ArgumentException("Input URI must represent a remote URL path", "existingFile");
// Do a WebRequest.Create call and attempt download... (Perhaps to MemoryStream for future use)
Hope that helps.
Andrew.